<commit_before>###############################################################################
##
##  Copyright (C) 2011-2014 Tavendo GmbH
##
##  This program is free software: you can redistribute it and/or modify
##  it under the terms of the GNU Affero General Public License, version 3,
##  as published by the Free Software Foundation.
##
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
##  GNU Affero General Public License for more details.
##
##  You should have received a copy of the GNU Affero General Public License
##  along with this program. If not, see <http://www.gnu.org/licenses/>.
##
###############################################################################

from __future__ import absolute_import

__all__ = ['run']

import os
import sys
import json
import argparse
import pkg_resources

from twisted.python import log
from twisted.python.reflect import qual

from autobahn.twisted.choosereactor import install_reactor

from crossbar.node import Node

def run_command_version(options):
   """
   Subcommand "crossbar version".
   """
   reactor = install_reactor(options.reactor, options.debug)

   ## Python
   ##
   py_ver = '.'.join([str(x) for x in list(sys.version_info[:3])])
   if options.debug:
      py_ver += " [%s]" % sys.version.replace('\n', ' ')

   ## Twisted / Reactor
   ##
   tx_ver = "%s-%s" % (pkg_resources.require("Twisted")[0].version, reactor.__class__.__name__)
   if options.debug:
      tx_ver += " [%s]" % qual(reactor.__class__)

   ## Autobahn
   ##
   import autobahn
   from autobahn.websocket.protocol import WebSocketProtocol
   ab_ver = pkg_resources.require("autobahn")[0].version
   if options.debug:
      ab_ver += " [%s]" % qual(WebSocketProtocol)

   ## UTF8 Validator
   ##
   from autobahn.websocket.utf8validator import Utf8Validator
   s = str(Utf8Validator)
   if 'wsaccel' in s:
      utf8_ver = 'wsaccel-%s' % pkg_resources.require('wsaccel')[0].version
   elif s.startswith('autobahn'):
      utf8_ver = 'autobahn'
   else:
      raise Exception("could not detect UTF8 validator type/version")
   if options.debug:
      utf8_ver += " [%s]" % qual(Utf8Validator)

   ## XOR Masker
   ##
   from autobahn.websocket.xormasker import XorMaskerNull
   s = str(XorMaskerNull)
   if 'wsaccel' in s:
      xor_ver = 'wsaccel-%s' % pkg_resources.require('wsaccel')[0].version
   elif s.startswith('autobahn'):
      xor_ver = 'autobahn'
   else:
      raise Exception("could not detect XOR masker type/version")
   if options.debug:
      xor_ver += " [%s]" % qual(XorMaskerNull)

   import crossbar

   print
   print "Crossbar.io software versions:"
   print
   print "Crossbar.io     : %s" % crossbar.__version__
   print "Autobahn        : %s" % ab_ver
   print "Twisted         : %s" % tx_ver
   print "Python          : %s" % py_ver
   print "UTF8 Validator  : %s" % utf8_ver
   print "XOR Masker      : %s" % xor_ver
   print

def run_command_init(options):
   """
   Subcommand "crossbar init".
   """
   from crossbar.template import TEMPLATES

   if options.template:
      if not TEMPLATES.has_key(options.template):
         raise Exception("No such Crossbar.io node template {}".format(options.template))
      else:
         template = TEMPLATES[options.template]
         #config = json.dumps(template, indent = 3, ensure_ascii = False, sort_keys = False)
         config = template
   else:
      raise Exception("Missing template to instantiate Crossbar.io node")

   if os.path.exists(options.cbdir):
      raise Exception("Path '{}' for Crossbar.io node directory already exists".format(options.cbdir))

   try:
      os.mkdir(options.cbdir)
   except Exception as e:
      raise Exception("Could not create Crossbar.io node directory '{}' [{}]".format(options.cbdir, e))

   with open(os.path.join(options.cbdir, 'config.json'), 'wb') as outfile:
      outfile.write(config)

   print("Crossbar.io node initialized at {}".format(os.path.abspath(options.cbdir)))

import crossbar

def run_command_start(options):
   """
   Subcommand "crossbar start".
   """
   ## start Twisted logging
   ##
   if not options.logdir:
      logfd = sys.stderr
   else:
      from twisted.python.logfile import DailyLogFile
      logfd = DailyLogFile.fromFullPath(os.path.join(options.logdir, 'node.log'))

   from crossbar.process import DefaultSystemFileLogObserver
   flo = DefaultSystemFileLogObserver(logfd, system = "Controller {}".format(os.getpid()))
   log.startLoggingWithObserver(flo.emit)

   log.msg("=" * 30 + " Crossbar.io " + "=" * 30 + "\n")

   log.msg("Crossbar.io {} node starting".format(crossbar.__version__))

   ## we use an Autobahn utility to import the "best" available Twisted reactor
   ##
   reactor = install_reactor(options.reactor, options.debug)

   #if options.debug:
   #   print("Running on reactor {}".format(reactor))

   ## create and start Crossbar.io node
   ##
   node = Node(reactor, options.cbdir, options.debug)
   node.start()

   ## enter event loop
   ##
   reactor.run()

def run():
   """
   Entry point of Crossbar.io.
   """
   ## create the top-level parser
   ##
   parser = argparse.ArgumentParser(prog = 'crossbar',
                                    description = "Crossbar.io - Polyglot application router - http://crossbar.io")

   ## top-level options
   ##
   parser.add_argument('-d',
                       '--debug',
                       action = 'store_true',
                       help = 'Debug on.')

   parser.add_argument('--reactor',
                       default = None,
                       choices = ['select', 'poll', 'epoll', 'kqueue', 'iocp'],
                       help = 'Explicit Twisted reactor selection')

   ## create subcommand parser
   ##
   subparsers = parser.add_subparsers(dest = 'command',
                                      title = 'commands',
                                      help = 'Crossbar.io command to run')

   ## "version" command
   ##
   parser_version = subparsers.add_parser('version',
                                          help = 'Print software versions.')

   parser_version.set_defaults(func = run_command_version)

   ## "init" command
   ##
   parser_init = subparsers.add_parser('init',
                                        help = 'Initialize a new Crossbar.io node.')

   parser_init.set_defaults(func = run_command_init)

   parser_init.add_argument('--template',
                             type = str,
                             default = 'router',
                             help = "Template for initialization")

   parser_init.add_argument('--cbdir',
                             type = str,
                             default = None,
                             help = "Crossbar.io node directory (overrides ${CROSSBAR_DIR} and the default ./.crossbar)")

   ## "start" command
   ##
   parser_start = subparsers.add_parser('start',
                                        help = 'Start a Crossbar.io node.')

   parser_start.set_defaults(func = run_command_start)

   parser_start.add_argument('--cbdir',
                             type = str,
                             default = None,
                             help = "Crossbar.io node directory (overrides ${CROSSBAR_DIR} and the default ./.crossbar)")

   parser_start.add_argument('--logdir',
                             type = str,
                             default = None,
                             help = "Crossbar.io log directory (default: <Crossbar Node Directory>/log)")

   parser_start.add_argument('--loglevel',
                              type = str,
                              default = 'info',
                              choices = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'],
                              help = "Server log level (overrides default 'info')")

   ## parse cmd line args
   ##
   options = parser.parse_args()

   ## Crossbar.io node directory
   ##
   if hasattr(options, 'cbdir') and not options.cbdir:
      if os.environ.has_key("CROSSBAR_DIR"):
         options.cbdir = os.environ['CROSSBAR_DIR']
      else:
         options.cbdir = '.crossbar'
   options.cbdir = os.path.abspath(options.cbdir)

   ## Log directory
   ##
   if options.logdir:
      options.logdir = os.path.abspath(os.path.join(options.cbdir, options.logdir))
      if not os.path.isdir(options.logdir):
         try:
            os.mkdir(options.logdir)
         except Exception as e:
            print("Could not create log directory: {}".format(e))
            sys.exit(1)

   ## run the subcommand selected
   ##
   options.func(options)

if __name__ == '__main__':
   run()
<commit_msg>fix cbdir treatment<commit_after>###############################################################################
##
##  Copyright (C) 2011-2014 Tavendo GmbH
##
##  This program is free software: you can redistribute it and/or modify
##  it under the terms of the GNU Affero General Public License, version 3,
##  as published by the Free Software Foundation.
##
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
##  GNU Affero General Public License for more details.
##
##  You should have received a copy of the GNU Affero General Public License
##  along with this program. If not, see <http://www.gnu.org/licenses/>.
##
###############################################################################

from __future__ import absolute_import

__all__ = ['run']

import os
import sys
import json
import argparse
import pkg_resources

from twisted.python import log
from twisted.python.reflect import qual

from autobahn.twisted.choosereactor import install_reactor

from crossbar.node import Node

def run_command_version(options):
   """
   Subcommand "crossbar version".
   """
   reactor = install_reactor(options.reactor, options.debug)

   ## Python
   ##
   py_ver = '.'.join([str(x) for x in list(sys.version_info[:3])])
   if options.debug:
      py_ver += " [%s]" % sys.version.replace('\n', ' ')

   ## Twisted / Reactor
   ##
   tx_ver = "%s-%s" % (pkg_resources.require("Twisted")[0].version, reactor.__class__.__name__)
   if options.debug:
      tx_ver += " [%s]" % qual(reactor.__class__)

   ## Autobahn
   ##
   import autobahn
   from autobahn.websocket.protocol import WebSocketProtocol
   ab_ver = pkg_resources.require("autobahn")[0].version
   if options.debug:
      ab_ver += " [%s]" % qual(WebSocketProtocol)

   ## UTF8 Validator
   ##
   from autobahn.websocket.utf8validator import Utf8Validator
   s = str(Utf8Validator)
   if 'wsaccel' in s:
      utf8_ver = 'wsaccel-%s' % pkg_resources.require('wsaccel')[0].version
   elif s.startswith('autobahn'):
      utf8_ver = 'autobahn'
   else:
      raise Exception("could not detect UTF8 validator type/version")
   if options.debug:
      utf8_ver += " [%s]" % qual(Utf8Validator)

   ## XOR Masker
   ##
   from autobahn.websocket.xormasker import XorMaskerNull
   s = str(XorMaskerNull)
   if 'wsaccel' in s:
      xor_ver = 'wsaccel-%s' % pkg_resources.require('wsaccel')[0].version
   elif s.startswith('autobahn'):
      xor_ver = 'autobahn'
   else:
      raise Exception("could not detect XOR masker type/version")
   if options.debug:
      xor_ver += " [%s]" % qual(XorMaskerNull)

   import crossbar

   print
   print "Crossbar.io software versions:"
   print
   print "Crossbar.io     : %s" % crossbar.__version__
   print "Autobahn        : %s" % ab_ver
   print "Twisted         : %s" % tx_ver
   print "Python          : %s" % py_ver
   print "UTF8 Validator  : %s" % utf8_ver
   print "XOR Masker      : %s" % xor_ver
   print

def run_command_init(options):
   """
   Subcommand "crossbar init".
   """
   from crossbar.template import TEMPLATES

   if options.template:
      if not TEMPLATES.has_key(options.template):
         raise Exception("No such Crossbar.io node template {}".format(options.template))
      else:
         template = TEMPLATES[options.template]
         #config = json.dumps(template, indent = 3, ensure_ascii = False, sort_keys = False)
         config = template
   else:
      raise Exception("Missing template to instantiate Crossbar.io node")

   if os.path.exists(options.cbdir):
      raise Exception("Path '{}' for Crossbar.io node directory already exists".format(options.cbdir))

   try:
      os.mkdir(options.cbdir)
   except Exception as e:
      raise Exception("Could not create Crossbar.io node directory '{}' [{}]".format(options.cbdir, e))

   with open(os.path.join(options.cbdir, 'config.json'), 'wb') as outfile:
      outfile.write(config)

   print("Crossbar.io node initialized at {}".format(os.path.abspath(options.cbdir)))

import crossbar

def run_command_start(options):
   """
   Subcommand "crossbar start".
   """
   ## start Twisted logging
   ##
   if not options.logdir:
      logfd = sys.stderr
   else:
      from twisted.python.logfile import DailyLogFile
      logfd = DailyLogFile.fromFullPath(os.path.join(options.logdir, 'node.log'))

   from crossbar.process import DefaultSystemFileLogObserver
   flo = DefaultSystemFileLogObserver(logfd, system = "Controller {}".format(os.getpid()))
   log.startLoggingWithObserver(flo.emit)

   log.msg("=" * 30 + " Crossbar.io " + "=" * 30 + "\n")

   log.msg("Crossbar.io {} node starting".format(crossbar.__version__))

   ## we use an Autobahn utility to import the "best" available Twisted reactor
   ##
   reactor = install_reactor(options.reactor, options.debug)

   #if options.debug:
   #   print("Running on reactor {}".format(reactor))

   ## create and start Crossbar.io node
   ##
   node = Node(reactor, options.cbdir, options.debug)
   node.start()

   ## enter event loop
   ##
   reactor.run()

def run():
   """
   Entry point of Crossbar.io.
   """
   ## create the top-level parser
   ##
   parser = argparse.ArgumentParser(prog = 'crossbar',
                                    description = "Crossbar.io - Polyglot application router - http://crossbar.io")

   ## top-level options
   ##
   parser.add_argument('-d',
                       '--debug',
                       action = 'store_true',
                       help = 'Debug on.')

   parser.add_argument('--reactor',
                       default = None,
                       choices = ['select', 'poll', 'epoll', 'kqueue', 'iocp'],
                       help = 'Explicit Twisted reactor selection')

   ## create subcommand parser
   ##
   subparsers = parser.add_subparsers(dest = 'command',
                                      title = 'commands',
                                      help = 'Crossbar.io command to run')

   ## "version" command
   ##
   parser_version = subparsers.add_parser('version',
                                          help = 'Print software versions.')

   parser_version.set_defaults(func = run_command_version)

   ## "init" command
   ##
   parser_init = subparsers.add_parser('init',
                                        help = 'Initialize a new Crossbar.io node.')

   parser_init.set_defaults(func = run_command_init)

   parser_init.add_argument('--template',
                             type = str,
                             default = 'router',
                             help = "Template for initialization")

   parser_init.add_argument('--cbdir',
                             type = str,
                             default = None,
                             help = "Crossbar.io node directory (overrides ${CROSSBAR_DIR} and the default ./.crossbar)")

   ## "start" command
   ##
   parser_start = subparsers.add_parser('start',
                                        help = 'Start a Crossbar.io node.')

   parser_start.set_defaults(func = run_command_start)

   parser_start.add_argument('--cbdir',
                             type = str,
                             default = None,
                             help = "Crossbar.io node directory (overrides ${CROSSBAR_DIR} and the default ./.crossbar)")

   parser_start.add_argument('--logdir',
                             type = str,
                             default = None,
                             help = "Crossbar.io log directory (default: <Crossbar Node Directory>/log)")

   parser_start.add_argument('--loglevel',
                              type = str,
                              default = 'info',
                              choices = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'],
                              help = "Server log level (overrides default 'info')")

   ## parse cmd line args
   ##
   options = parser.parse_args()

   ## Crossbar.io node directory
   ##
   if hasattr(options, 'cbdir'):
      if not options.cbdir:
         if os.environ.has_key("CROSSBAR_DIR"):
            options.cbdir = os.environ['CROSSBAR_DIR']
         else:
            options.cbdir = '.crossbar'
      options.cbdir = os.path.abspath(options.cbdir)

   ## Log directory
   ##
   if options.logdir:
      options.logdir = os.path.abspath(os.path.join(options.cbdir, options.logdir))
      if not os.path.isdir(options.logdir):
         try:
            os.mkdir(options.logdir)
         except Exception as e:
            print("Could not create log directory: {}".format(e))
            sys.exit(1)

   ## run the subcommand selected
   ##
   options.func(options)

if __name__ == '__main__':
   run()
<|endoftext|>


<commit_before>"""
Universidad Nacional de La Matanza
Catedra Lenguajes y Compiladores - 2013
Mariano Francischini, Alejandro Giorgi, Roberto Bravo

TP Compilador
Basado en PLY (Python Lex-Yacc)
    http://www.dabeaz.com/ply/
    Ej: http://www.dalkescientific.com/writings/NBN/parsing_with_ply.html
"""
# coding=utf8
import ply.yacc as yacc
from lexer import Lexer, tokens
from tabla_sim import TablaSim, Simbolo
import sys

def concatena(lista):
    """
    Test. Por ahora concatena los operandos como string en vez
    de generar codigo (tercetos)
    """
    string = ""
    for item in lista[1:]:
        string += str(item)
    return string

tabla_sim = TablaSim()
tabla_sim.ambito_actual = 'main'

class Terceto():
    lista = []

    def __init__(self, *args):
        """ Crea y agrega un terceto a la lista """
        self.items = args
        self.id = len(Terceto.lista)

        Terceto.lista.append(self)
    def __str__(self):
        return "ter[%s]" % self.id

    def __repr__(self):
        """ ToString del terceto """
        items = []
        for item in self.items:
            items.append(str(item))
        return "%s: (%s)" % (self.id, ', '.join(items))

nro_regla = 0
def get_nro_regla():
    """ Contador de numero de regla 'actual'. Incrementa a medida que se crean"""
    global nro_regla
    regla = "ter[%s]" % nro_regla
    nro_regla += 1
    return regla

"""
    ###############################
    BNF y mapeo al codigo resultado
    Start Symbol: "programa"
    ###############################
"""
def p_programa(p):
    'programa : bloque_dec main'
    p[0] = Terceto(p[2])

def p_bloque_dec(p):
    ('bloque_dec : PR_DEC DOS_PUNTOS '
        'ABRE_BLOQUE '
            'declaraciones '
        'CIERRA_BLOQUE '
     'PR_ENDEC FIN_LINEA ')
    p[0] = p[4]

    if tabla_sim.ambito_actual == 'main':
        # Reseteamos ambito_actual una vez que lo usa el main para su dec.
        tabla_sim.ambito_actual = None

def p_declaraciones(p):
    'declaraciones : declaracion FIN_LINEA declaraciones'
    pass

def p_declaraciones_simple(p):
    'declaraciones : declaracion'
    pass

def p_declaracion(p):
    """
    declaracion : tipo_dato DOS_PUNTOS lista_ids
    """
    # Tabla de simbolos
    # TODO: Solo acepta la declaracion de un ID en lista_ids
    simbolo = tabla_sim.declarar_variable(tipo=p[1], lista_ids=p[3])

    p[0] = simbolo

def p_lista_ids(p):
    """
    lista_ids : ID COMA lista_ids
    """
    p[0] = Terceto(p[1], p[3])

def p_lista_ids_simple(p):
    """
    lista_ids : ID
    """
    p[0] = p[1]

def p_main(p):
    """
    main : main bloque
    main : main funcion
    """
    p[0] = Terceto(p[1], p[2])

def p_main_simple(p):
    """
    main : bloque
    main : funcion
    """
    p[0] = p[1]

def p_funcion(p):
    ('funcion : '
        'PR_DEF ID DOS_PUNTOS tipo_dato '
            'ABRE_BLOQUE '
                'bloque_dec '
                'bloque '
            'CIERRA_BLOQUE '
        'PR_RETURN expresion FIN_LINEA'
     )

    # Tabla de simbolos
    simbolo = tabla_sim.declarar_funcion(nombre=p[2])

    # Terceto: id, tipo_dato, bloque, return_expresion
    p[0] = Terceto(simbolo, p[4], p[7], p[10])

    # Termina la funcion. Reset ambito
    tabla_sim.ambito_actual = None

def p_tipo_dato(p):
    """
    tipo_dato : PR_INT
    tipo_dato : PR_FLOAT
    tipo_dato : PR_STRING
    """
    p[0] = p[1]

def p_bloque(p):
    """
    bloque : sentencia bloque
    """
    p[0] = Terceto(p[1], p[2])

def p_bloque_simple(p):
    """
    bloque : sentencia
    """
    p[0] = p[1]

def p_sentencia(p):
    """
    sentencia : asig
    sentencia : sentencia_condicional
    sentencia : sentencia_while
    sentencia : sentencia_print
    sentencia : sentencia_percent
    """
    p[0] = p[1]

def p_sentencia_sentencia(p):
    """
    sentencia : sentencia FIN_LINEA sentencia
    """
    p[0] = Terceto(p[1], p[3])

def p_sentencia_print(p):
    """
    sentencia_print : PR_PRINT ID
    """
    simbolo = tabla_sim.obtener_variable(p[2])
    p[0] = Terceto(p[1], simbolo)

def p_sentencia_while(p):
    """
    sentencia_while : PR_WHILE condicion DOS_PUNTOS ABRE_BLOQUE bloque CIERRA_BLOQUE
    """
    # (while, condicion, bloque)
    p[0] = Terceto(p[1], p[2], p[5])

def p_sentencia_condicional(p):
    'sentencia_condicional : PR_IF condicion DOS_PUNTOS ABRE_BLOQUE bloque CIERRA_BLOQUE'
    # (if, condicion, bloque)
    p[0] = Terceto(p[1], p[2], p[5])

def p_sentencia_condicional_else(p):
    """
     sentencia_condicional : PR_IF condicion DOS_PUNTOS ABRE_BLOQUE bloque CIERRA_BLOQUE PR_ELSE ABRE_BLOQUE bloque CIERRA_BLOQUE
    """
    # (if, condicion, bloque, else, bloque)
    p[0] = Terceto(p[1], p[2], p[5], p[7], p[9])

def p_sentencia_percent(p):
    """
    sentencia_percent : PR_PERCENT factor COMA factor
    """
    # ej: (percent, expresion, expresion)
    p[0] = Terceto(p[1], p[2], p[4])

def p_asig(p):
    """
    asig : ID OP_AS expresion
    asig : ID OP_AS asig
    asig : ID OP_AS cte_string
    """
    simbolo = tabla_sim.obtener_variable(p[1])
    # (=, ID, exp)
    p[0] = Terceto(p[2], simbolo, p[3])

def p_cte_string(p):
    """ cte_string : CTE_STRING """
    p[0] = tabla_sim.declarar_cte_string(p[1])

def p_condicion(p):
    """
    condicion : expresion OP_IGUALDAD expresion
    condicion : expresion OP_MAYOR expresion
    condicion : expresion OP_MENOR expresion
    condicion : expresion OP_MENORIGUAL expresion
    condicion : expresion OP_DISTINTO expresion
    condicion : condicion PR_AND condicion
    condicion : condicion PR_OR condicion
    """
    # ej: (<, expresion, expresion)
    p[0] = Terceto(p[2], p[1], p[3])

def p_condicion_between(p):
    """
    condicion : factor PR_BETWEEN factor PR_AND factor
    """
    # ej: (<, expresion, expresion)
    p[0] = Terceto(p[2], p[1], p[3], p[5])

def p_expresion(p):
    """
    expresion : expresion OP_SUMA termino
    expresion : expresion OP_RESTA termino
    expresion : expresion OP_MUL termino
    expresion : expresion OP_DIV termino
    """
    # (+, exp, ter)
    p[0] = Terceto(p[2], p[1], p[3])

def p_expression_term(p):
    'expresion : termino'
    p[0] = p[1]

def p_term_factor(p):
    'termino : factor'
    p[0] = p[1]

def p_factor_parentesis(p):
    """
    factor : PAREN_ABRE expresion PAREN_CIERRA
    """
    p[0] = p[2]

def p_factor_id(p):
    """
    factor : ID
    """
    # try:
    simbolo = tabla_sim.obtener_variable(p[1])
    p[0] = simbolo
    # except TypeError:
    #    p[0] = p[1]

def p_factor_cte(p):
    """
    factor : CTE_ENT
    factor : CTE_REAL
    """
    p[0] = p[1]

# Error rule for syntax errors
def p_error(p):
    raise TypeError("Syntax error: %s" % str(p))

# Build the parser

yyparse = yacc.yacc(debug=1)
yylex = Lexer()

try:
    filename = sys.argv[1]
except:
    filename = "fuente.zz"
fuente = open(filename).read()

print '\nTokens:\n=======\n'
result = yyparse.parse(fuente, lexer=yylex)

if result is not None:
    print '\nSimbolos:\n=========\n'
    with open('simbolos.txt', 'w') as archivo:
            print tabla_sim
            archivo.write("%s\n" % tabla_sim)

    print '\nTercetos:\n=========\n'
    with open('intermedia.txt', 'w') as archivo:
        for terceto in Terceto.lista:
            print repr(terceto)
            archivo.write("%s\n" % repr(terceto))
else:
    print "\nError!!"
<commit_msg>Se agrega una lista temporal de ids que luego se recorre para crear los simbolos<commit_after>"""
Universidad Nacional de La Matanza
Catedra Lenguajes y Compiladores - 2013
Mariano Francischini, Alejandro Giorgi, Roberto Bravo

TP Compilador
Basado en PLY (Python Lex-Yacc)
    http://www.dabeaz.com/ply/
    Ej: http://www.dalkescientific.com/writings/NBN/parsing_with_ply.html
"""
# coding=utf8
import ply.yacc as yacc
from lexer import Lexer, tokens
from tabla_sim import TablaSim, Simbolo
import sys

def concatena(lista):
    """
    Test. Por ahora concatena los operandos como string en vez
    de generar codigo (tercetos)
    """
    string = ""
    for item in lista[1:]:
        string += str(item)
    return string

tabla_sim = TablaSim()
tabla_sim.ambito_actual = 'main'

class Terceto():
    lista = []

    def __init__(self, *args):
        """ Crea y agrega un terceto a la lista """
        self.items = args
        self.id = len(Terceto.lista)

        Terceto.lista.append(self)
    def __str__(self):
        return "ter[%s]" % self.id

    def __repr__(self):
        """ ToString del terceto """
        items = []
        for item in self.items:
            items.append(str(item))
        return "%s: (%s)" % (self.id, ', '.join(items))

nro_regla = 0
def get_nro_regla():
    """ Contador de numero de regla 'actual'. Incrementa a medida que se crean"""
    global nro_regla
    regla = "ter[%s]" % nro_regla
    nro_regla += 1
    return regla

"""
    ###############################
    BNF y mapeo al codigo resultado
    Start Symbol: "programa"
    ###############################
"""
lista_ids = []

def p_programa(p):
    'programa : bloque_dec main'
    p[0] = Terceto(p[2])

def p_bloque_dec(p):
    ('bloque_dec : PR_DEC DOS_PUNTOS '
        'ABRE_BLOQUE '
            'declaraciones '
        'CIERRA_BLOQUE '
     'PR_ENDEC FIN_LINEA ')
    p[0] = p[4]

    if tabla_sim.ambito_actual == 'main':
        # Reseteamos ambito_actual una vez que lo usa el main para su dec.
        tabla_sim.ambito_actual = None

def p_declaraciones(p):
    'declaraciones : declaracion FIN_LINEA declaraciones'
    pass

def p_declaraciones_simple(p):
    'declaraciones : declaracion'
    pass

def p_declaracion(p):
    """
    declaracion : tipo_dato DOS_PUNTOS lista_ids
    """
    # Tabla de simbolos
    # TODO: Solo acepta la declaracion de un ID en lista_ids
    for variable in lista_ids:
        tabla_sim.declarar_variable(p[1], variable)
    del lista_ids[0:len(lista_ids)]
    #simbolo = tabla_sim.declarar_variable(tipo=p[1], lista_ids=p[3])

    #p[0] = simbolo

def p_lista_ids(p):
    """
    lista_ids : ID COMA lista_ids
    """
    lista_ids.append(p[1])
    p[0] = Terceto(p[1], p[3])

def p_lista_ids_simple(p):
    """
    lista_ids : ID
    """
    lista_ids.append(p[1])
    p[0] = p[1]

def p_main(p):
    """
    main : main bloque
    main : main funcion
    """
    p[0] = Terceto(p[1], p[2])

def p_main_simple(p):
    """
    main : bloque
    main : funcion
    """
    p[0] = p[1]

def p_funcion(p):
    ('funcion : '
        'PR_DEF ID DOS_PUNTOS tipo_dato '
            'ABRE_BLOQUE '
                'bloque_dec '
                'bloque '
            'CIERRA_BLOQUE '
        'PR_RETURN expresion FIN_LINEA'
     )

    # Tabla de simbolos
    simbolo = tabla_sim.declarar_funcion(nombre=p[2])

    # Terceto: id, tipo_dato, bloque, return_expresion
    p[0] = Terceto(simbolo, p[4], p[7], p[10])

    # Termina la funcion. Reset ambito
    tabla_sim.ambito_actual = None

def p_tipo_dato(p):
    """
    tipo_dato : PR_INT
    tipo_dato : PR_FLOAT
    tipo_dato : PR_STRING
    """
    p[0] = p[1]

def p_bloque(p):
    """
    bloque : sentencia bloque
    """
    p[0] = Terceto(p[1], p[2])

def p_bloque_simple(p):
    """
    bloque : sentencia
    """
    p[0] = p[1]

def p_sentencia(p):
    """
    sentencia : asig
    sentencia : sentencia_condicional
    sentencia : sentencia_while
    sentencia : sentencia_print
    sentencia : sentencia_percent
    """
    p[0] = p[1]

def p_sentencia_sentencia(p):
    """
    sentencia : sentencia FIN_LINEA sentencia
    """
    p[0] = Terceto(p[1], p[3])

def p_sentencia_print(p):
    """
    sentencia_print : PR_PRINT ID
    """
    simbolo = tabla_sim.obtener_variable(p[2])
    p[0] = Terceto(p[1], simbolo)

def p_sentencia_while(p):
    """
    sentencia_while : PR_WHILE condicion DOS_PUNTOS ABRE_BLOQUE bloque CIERRA_BLOQUE
    """
    # (while, condicion, bloque)
    p[0] = Terceto(p[1], p[2], p[5])

def p_sentencia_condicional(p):
    'sentencia_condicional : PR_IF condicion DOS_PUNTOS ABRE_BLOQUE bloque CIERRA_BLOQUE'
    # (if, condicion, bloque)
    p[0] = Terceto(p[1], p[2], p[5])

def p_sentencia_condicional_else(p):
    """
     sentencia_condicional : PR_IF condicion DOS_PUNTOS ABRE_BLOQUE bloque CIERRA_BLOQUE PR_ELSE ABRE_BLOQUE bloque CIERRA_BLOQUE
    """
    # (if, condicion, bloque, else, bloque)
    p[0] = Terceto(p[1], p[2], p[5], p[7], p[9])

def p_sentencia_percent(p):
    """
    sentencia_percent : PR_PERCENT factor COMA factor
    """
    # ej: (percent, expresion, expresion)
    p[0] = Terceto(p[1], p[2], p[4])

def p_asig(p):
    """
    asig : ID OP_AS expresion
    asig : ID OP_AS asig
    asig : ID OP_AS cte_string
    """
    simbolo = tabla_sim.obtener_variable(p[1])
    # (=, ID, exp)
    p[0] = Terceto(p[2], simbolo, p[3])

def p_cte_string(p):
    """ cte_string : CTE_STRING """
    p[0] = tabla_sim.declarar_cte_string(p[1])

def p_condicion(p):
    """
    condicion : expresion OP_IGUALDAD expresion
    condicion : expresion OP_MAYOR expresion
    condicion : expresion OP_MENOR expresion
    condicion : expresion OP_MENORIGUAL expresion
    condicion : expresion OP_DISTINTO expresion
    condicion : condicion PR_AND condicion
    condicion : condicion PR_OR condicion
    """
    # ej: (<, expresion, expresion)
    p[0] = Terceto(p[2], p[1], p[3])

def p_condicion_between(p):
    """
    condicion : factor PR_BETWEEN factor PR_AND factor
    """
    # ej: (<, expresion, expresion)
    p[0] = Terceto(p[2], p[1], p[3], p[5])

def p_expresion(p):
    """
    expresion : expresion OP_SUMA termino
    expresion : expresion OP_RESTA termino
    expresion : expresion OP_MUL termino
    expresion : expresion OP_DIV termino
    """
    # (+, exp, ter)
    p[0] = Terceto(p[2], p[1], p[3])

def p_expression_term(p):
    'expresion : termino'
    p[0] = p[1]

def p_term_factor(p):
    'termino : factor'
    p[0] = p[1]

def p_factor_parentesis(p):
    """
    factor : PAREN_ABRE expresion PAREN_CIERRA
    """
    p[0] = p[2]

def p_factor_id(p):
    """
    factor : ID
    """
    # try:
    simbolo = tabla_sim.obtener_variable(p[1])
    p[0] = simbolo
    # except TypeError:
    #    p[0] = p[1]

def p_factor_cte(p):
    """
    factor : CTE_ENT
    factor : CTE_REAL
    """
    p[0] = p[1]

# Error rule for syntax errors
def p_error(p):
    raise TypeError("Syntax error: %s" % str(p))

# Build the parser

yyparse = yacc.yacc(debug=1)
yylex = Lexer()

try:
    filename = sys.argv[1]
except:
    filename = "fuente.zz"
fuente = open(filename).read()

print '\nTokens:\n=======\n'
result = yyparse.parse(fuente, lexer=yylex)

if result is not None:
    print '\nSimbolos:\n=========\n'
    with open('simbolos.txt', 'w') as archivo:
            print tabla_sim
            archivo.write("%s\n" % tabla_sim)

    print '\nTercetos:\n=========\n'
    with open('intermedia.txt', 'w') as archivo:
        for terceto in Terceto.lista:
            print repr(terceto)
            archivo.write("%s\n" % repr(terceto))
else:
    print "\nError!!"
<|endoftext|>


<commit_before>#                                              LOFAR TRANSIENTS IMAGING PIPELINE
#
#                                        BBS (BlackBoard Selfcal) wrapper recipe
#                                                                Evert Rol, 2012
#                                                      software@transientskp.org
# ------------------------------------------------------------------------------

from __future__ import with_statement
import subprocess
import sys
import os
import threading
import tempfile
import shutil
import time
import signal

from lofar.parameterset import parameterset

from lofarpipe.support.baserecipe import BaseRecipe
from lofarpipe.support.group_data import load_data_map, store_data_map
from lofarpipe.support.lofarexceptions import PipelineException
from lofarpipe.support.pipelinelogging import CatchLog4CPlus
from lofarpipe.support.pipelinelogging import log_process_output
from lofarpipe.support.remotecommand import run_remote_command
from lofarpipe.support.remotecommand import ComputeJob
from lofarpipe.support.jobserver import job_server
from lofarpipe.support.parset import Parset
from lofarpipe.support.group_data import store_data_map
import lofarpipe.support.utilities as utilities
import lofarpipe.support.lofaringredient as ingredient

class bbs(BaseRecipe):
    """
    The bbs recipe acts as a wrapper around new_bbs, introducing one
    extra parameter: nproc. Based on nproc, it runs new_bbs multiple
    times, each with a different mapping file that is created from the
    original mapfile giving as input.

    **Arguments**

    A mapfile describing the data to be processed.
    """
    inputs = {
        'control_exec': ingredient.ExecField(
            '--control-exec',
            dest="control_exec",
            help="BBS Control executable"
        ),
        'kernel_exec': ingredient.ExecField(
            '--kernel-exec',
            dest="kernel_exec",
            help="BBS Kernel executable"
        ),
        'initscript': ingredient.FileField(
            '--initscript',
            dest="initscript",
            help="Initscript to source (ie, lofarinit.sh)"
        ),
        'parset': ingredient.FileField(
            '-p', '--parset',
            dest="parset",
            help="BBS configuration parset"
        ),
        'db_key': ingredient.StringField(
            '--db-key',
            dest="db_key",
            help="Key to identify BBS session"
        ),
        'db_host': ingredient.StringField(
            '--db-host',
            dest="db_host",
            help="Database host with optional port (e.g. ldb001:5432)"
        ),
        'db_user': ingredient.StringField(
            '--db-user',
            dest="db_user",
            help="Database user"
        ),
        'db_name': ingredient.StringField(
            '--db-name',
            dest="db_name",
            help="Database name"
        ),
        'instrument_mapfile': ingredient.FileField(
            '--instrument-mapfile',
            help="Full path to the mapfile containing the names of the "
                 "instrument model files generated by the `parmdb` recipe"
        ),
        'sky_mapfile': ingredient.FileField(
            '--sky-mapfile',
            help="Full path to the mapfile containing the names of the "
                 "sky model files generated by the `sourcedb` recipe"
        ),
        'nproc': ingredient.IntField(
            '--nproc',
            help="Maximum number of simultaneous processes per compute node",
            default=8
        ),
        'data_mapfile': ingredient.StringField(
            '--data-mapfile',
            help="Full path to the mapfile containing the names of the "
                 "data files that were processed by BBS (clobbered if exists)"
        )
    }
    outputs = {
        'mapfile': ingredient.FileField(
            help="Full path to a mapfile describing the processed data"
        )
    }

    def _make_partial_bbs_map(self):
        """
        Created a list of mapfile tuples from the full data mapfile,
        the instrument mapfile and the sky mapfile, but limited for
        nproc processes per host.

        It is assumed that the data, instrument and sky map files list
        their entries in corresponding order, i.e., the element i
        matches the same subband in all three mapfiles. The parmdb and
        sourcedb tasks should have taken care of this.
        """

        self.logger.debug("Creating BBS map-file using %s, %s, %s",
                          self.inputs['args'][0],
                          self.inputs['instrument_mapfile'],
                          self.inputs['sky_mapfile'])
        data_map = load_data_map(self.inputs['args'][0])
        instrument_map = load_data_map(self.inputs['instrument_mapfile'])
        sky_map = load_data_map(self.inputs['sky_mapfile'])
        nproc = self.inputs['nproc']
        mapfiles = {} #{'data': {}, 'instrument': {}, 'sky': {}}
        # This works per host, not per (sub)cluster.  We assume,
        # however, that the appropriate host/cluster to file mapping
        # has been done correctly before this task.
        # Firstly, we create a list of data, instrument and sky tuples
        # mapped to each host
        host_mapping = {}
        for i, host_data in enumerate(data_map):
            host, data = host_data
            instrument = instrument_map[i][1]
            sky = sky_map[i][1]
            host_mapping.setdefault(host, []).append((data, instrument, sky))
        # Secondly, we iterate through each host, chopping the lists up into
        # parts that are nproc long
        # We store the separate chopped lists into mapfiles
        for host, values in host_mapping.iteritems():
            data = [value[0] for value in values]
            instrument = [value[1] for value in values]
            sky = [value[2] for value in values]
            l = len(data)
            subdata = [data[i:i+nproc] for i in range(0, l, nproc)]
            subinstrument = [instrument[i:i+nproc] for i in range(0, l, nproc)]
            subsky = [sky[i:i+nproc] for i in range(0, l, nproc)]
            for isubset, sublist in enumerate(zip(subdata, subinstrument, subsky)):
                mapfiles.setdefault(isubset, {}).setdefault(host, {
                    'data': sublist[0],
                    'instrument': sublist[1],
                    'sky': sublist[2]})
        sub_mapfiles = []
        path = {}
        # Step through the subprocesses
        for mapping in mapfiles.values():
            submapping = {'data': [], 'instrument': [], 'sky': []}
            for key in ('data', 'instrument', 'sky'):
                submapping = []
                for host, maps in mapping.iteritems():
                    for value in maps[key]:
                        submapping.append((host, value))
                fh, path[key] = tempfile.mkstemp(suffix="_%s_mapfile" % key, dir=self.config.get(
                    'layout', 'parset_directory'))
                os.close(fh)
                store_data_map(path[key], submapping)
            sub_mapfiles.append((path['data'], path['instrument'], path['sky']))
        return sub_mapfiles

    def _combine_mapfiles(self, mapfiles):
        mapping = {}
        for mapfile in mapfiles:
            datamap = parameterset(mapfile)
            for host in datamap.keys():
                mapping.setdefault(host, []).extend(
                    datamap.getStringVector(host, []))
        mapfile = []
        for host, data in mapping.items():
            mapfile.append((host, data)) #addStringVector(host, data)
        return mapfile

    def go(self):
        self.logger.info("Starting BBS run")
        super(bbs, self).go()

        inputs = dict(self.inputs)
        del inputs['nproc']
        mapfiles = self._make_partial_bbs_map()
        self.logger.debug("temporary sub mapfiles = %s", str(mapfiles))
        new_mapfiles = []
        for mapfile in mapfiles:
            inputs['args'] = [mapfile[0]]
            inputs['instrument_mapfile'] = mapfile[1]
            inputs['sky_mapfile'] = mapfile[2]
            self.logger.info("mapfile = %s", str(mapfile))
            outputs = ingredient.LOFARoutput()
            fh, path = tempfile.mkstemp(suffix="_compute_mapfile", dir=self.config.get(
                'layout', 'parset_directory'))
            os.close(fh)
            inputs['data_mapfile'] = path
            self.cook_recipe("new_bbs", inputs, outputs)
            self.logger.debug("outputs = %s", str(outputs))
            new_mapfiles.append(outputs['mapfile'])
            # Clean up temporary input map files
            for tmpfile in mapfile:
                os.remove(tmpfile)
        mapfile = self._combine_mapfiles(new_mapfiles)
        store_data_map(self.inputs['data_mapfile'], mapfile)
        #mapfile.writeFile(self.inputs['data_mapfile'])
        # Clean up temporary output map files
        for new_mapfile in new_mapfiles:
            os.remove(new_mapfile)
        self.outputs['mapfile'] = self.inputs['data_mapfile']
        return 0

if __name__ == '__main__':
    sys.exit(new_bbs().main())
<commit_msg>Bug fix: wrapper bbs recipe now correctly creates the output mapping file<commit_after>#                                              LOFAR TRANSIENTS IMAGING PIPELINE
#
#                                        BBS (BlackBoard Selfcal) wrapper recipe
#                                                                Evert Rol, 2012
#                                                      software@transientskp.org
# ------------------------------------------------------------------------------

from __future__ import with_statement
import subprocess
import sys
import os
import threading
import tempfile
import shutil
import time
import signal

from lofar.parameterset import parameterset

from lofarpipe.support.baserecipe import BaseRecipe
from lofarpipe.support.group_data import load_data_map, store_data_map
from lofarpipe.support.lofarexceptions import PipelineException
from lofarpipe.support.pipelinelogging import CatchLog4CPlus
from lofarpipe.support.pipelinelogging import log_process_output
from lofarpipe.support.remotecommand import run_remote_command
from lofarpipe.support.remotecommand import ComputeJob
from lofarpipe.support.jobserver import job_server
from lofarpipe.support.parset import Parset
from lofarpipe.support.group_data import store_data_map
import lofarpipe.support.utilities as utilities
import lofarpipe.support.lofaringredient as ingredient

class bbs(BaseRecipe):
    """
    The bbs recipe acts as a wrapper around new_bbs, introducing one
    extra parameter: nproc. Based on nproc, it runs new_bbs multiple
    times, each with a different mapping file that is created from the
    original mapfile giving as input.

    **Arguments**

    A mapfile describing the data to be processed.
    """
    inputs = {
        'control_exec': ingredient.ExecField(
            '--control-exec',
            dest="control_exec",
            help="BBS Control executable"
        ),
        'kernel_exec': ingredient.ExecField(
            '--kernel-exec',
            dest="kernel_exec",
            help="BBS Kernel executable"
        ),
        'initscript': ingredient.FileField(
            '--initscript',
            dest="initscript",
            help="Initscript to source (ie, lofarinit.sh)"
        ),
        'parset': ingredient.FileField(
            '-p', '--parset',
            dest="parset",
            help="BBS configuration parset"
        ),
        'db_key': ingredient.StringField(
            '--db-key',
            dest="db_key",
            help="Key to identify BBS session"
        ),
        'db_host': ingredient.StringField(
            '--db-host',
            dest="db_host",
            help="Database host with optional port (e.g. ldb001:5432)"
        ),
        'db_user': ingredient.StringField(
            '--db-user',
            dest="db_user",
            help="Database user"
        ),
        'db_name': ingredient.StringField(
            '--db-name',
            dest="db_name",
            help="Database name"
        ),
        'instrument_mapfile': ingredient.FileField(
            '--instrument-mapfile',
            help="Full path to the mapfile containing the names of the "
                 "instrument model files generated by the `parmdb` recipe"
        ),
        'sky_mapfile': ingredient.FileField(
            '--sky-mapfile',
            help="Full path to the mapfile containing the names of the "
                 "sky model files generated by the `sourcedb` recipe"
        ),
        'nproc': ingredient.IntField(
            '--nproc',
            help="Maximum number of simultaneous processes per compute node",
            default=8
        ),
        'data_mapfile': ingredient.StringField(
            '--data-mapfile',
            help="Full path to the mapfile containing the names of the "
                 "data files that were processed by BBS (clobbered if exists)"
        )
    }
    outputs = {
        'mapfile': ingredient.FileField(
            help="Full path to a mapfile describing the processed data"
        )
    }

    def _make_partial_bbs_map(self):
        """
        Created a list of mapfile tuples from the full data mapfile,
        the instrument mapfile and the sky mapfile, but limited for
        nproc processes per host.

        It is assumed that the data, instrument and sky map files list
        their entries in corresponding order, i.e., the element i
        matches the same subband in all three mapfiles. The parmdb and
        sourcedb tasks should have taken care of this.
        """

        self.logger.debug("Creating BBS map-file using %s, %s, %s",
                          self.inputs['args'][0],
                          self.inputs['instrument_mapfile'],
                          self.inputs['sky_mapfile'])
        data_map = load_data_map(self.inputs['args'][0])
        instrument_map = load_data_map(self.inputs['instrument_mapfile'])
        sky_map = load_data_map(self.inputs['sky_mapfile'])
        nproc = self.inputs['nproc']
        mapfiles = {} #{'data': {}, 'instrument': {}, 'sky': {}}
        # This works per host, not per (sub)cluster.  We assume,
        # however, that the appropriate host/cluster to file mapping
        # has been done correctly before this task.
        # Firstly, we create a list of data, instrument and sky tuples
        # mapped to each host
        host_mapping = {}
        for i, host_data in enumerate(data_map):
            host, data = host_data
            instrument = instrument_map[i][1]
            sky = sky_map[i][1]
            host_mapping.setdefault(host, []).append((data, instrument, sky))
        # Secondly, we iterate through each host, chopping the lists up into
        # parts that are nproc long
        # We store the separate chopped lists into mapfiles
        for host, values in host_mapping.iteritems():
            data = [value[0] for value in values]
            instrument = [value[1] for value in values]
            sky = [value[2] for value in values]
            l = len(data)
            subdata = [data[i:i+nproc] for i in range(0, l, nproc)]
            subinstrument = [instrument[i:i+nproc] for i in range(0, l, nproc)]
            subsky = [sky[i:i+nproc] for i in range(0, l, nproc)]
            for isubset, sublist in enumerate(zip(subdata, subinstrument, subsky)):
                mapfiles.setdefault(isubset, {}).setdefault(host, {
                    'data': sublist[0],
                    'instrument': sublist[1],
                    'sky': sublist[2]})
        sub_mapfiles = []
        path = {}
        # Step through the subprocesses
        for mapping in mapfiles.values():
            submapping = {'data': [], 'instrument': [], 'sky': []}
            for key in ('data', 'instrument', 'sky'):
                submapping = []
                for host, maps in mapping.iteritems():
                    for value in maps[key]:
                        submapping.append((host, value))
                fh, path[key] = tempfile.mkstemp(suffix="_%s_mapfile" % key, dir=self.config.get(
                    'layout', 'parset_directory'))
                os.close(fh)
                store_data_map(path[key], submapping)
            sub_mapfiles.append((path['data'], path['instrument'], path['sky']))
        return sub_mapfiles

    def _combine_mapfiles(self, mapfiles):
        combined_mapfile = []
        for mapfile in mapfiles:
            datamap = load_data_map(mapfile)
            combined_mapfile.extend(datamap)
        return combined_mapfile

    def go(self):
        self.logger.info("Starting BBS run")
        super(bbs, self).go()

        inputs = dict(self.inputs)
        del inputs['nproc']
        mapfiles = self._make_partial_bbs_map()
        self.logger.debug("temporary sub mapfiles = %s", str(mapfiles))
        new_mapfiles = []
        for mapfile in mapfiles:
            inputs['args'] = [mapfile[0]]
            inputs['instrument_mapfile'] = mapfile[1]
            inputs['sky_mapfile'] = mapfile[2]
            self.logger.info("mapfile = %s", str(mapfile))
            outputs = ingredient.LOFARoutput()
            fh, path = tempfile.mkstemp(suffix="_compute_mapfile", dir=self.config.get(
                'layout', 'parset_directory'))
            os.close(fh)
            inputs['data_mapfile'] = path
            self.cook_recipe("new_bbs", inputs, outputs)
            self.logger.debug("outputs = %s", str(outputs))
            new_mapfiles.append(outputs['mapfile'])
            # Clean up temporary input map files
            for tmpfile in mapfile:
                os.remove(tmpfile)
        mapfile = self._combine_mapfiles(new_mapfiles)
        store_data_map(self.inputs['data_mapfile'], mapfile)
        # Clean up temporary output map files
        for new_mapfile in new_mapfiles:
            os.remove(new_mapfile)
        self.outputs['mapfile'] = self.inputs['data_mapfile']
        return 0

if __name__ == '__main__':
    sys.exit(new_bbs().main())
<|endoftext|>


<commit_before>import os
import subprocess
import click

script_folder="./scripts"

def _run_script(script, args, action_msg):
    logging.info(action_msg)
    try:
        subprocess.run([os.path.join(script_folder, script), *args], shell=True, check=True)
    except CalledProcessError as e:
        logging.error(e)

class Config(object):
    def __init__(self):
        self.servers = None
        self.start_at = None
        self.outdir = None

pass_config = click.make_pass_decorator(Config, ensure=True)

@click.group()
@click.option('--num-servers', default=8)
@click.option('--start-at', default=1)
@click.option('--server-dir', type=click.Path(), default='./servers')
@pass_config
def cli(config, num_servers, start_at, server_dir):
    config.num_servers = num_servers
    config.start_at = start_at
    config.server_dir = server_dir

@cli.command()
@pass_config
def scaffold(config):
    for i in range(config.start_at, config.start_at + config.num_servers):
        os.makedirs(os.path.join(config.server_dir, '{:02}'.format(i)))
        os.makedirs(os.path.join(config.server_dir, '.{:02}'.format(i), 'upper'))
        os.makedirs(os.path.join(config.server_dir, '.{:02}'.format(i), 'work'))

@cli.command()
@click.option('--root-dir', type=click.Path(), default='./rootserver')
@pass_config
def mount(config, root_dir):
    for i in range(config.start_at, config.start_at + config.num_servers):
        _run_script(script="mount_server.sh",
                    args=['{:02}'.format(i), root_dir, config.server_dir],
                    action_msg="Mounting server {:02}".format(i))

@cli.command()
@pass_config
def unmount(config):
    for i in range(config.start_at, config.start_at + config.num_servers):
        _run_script(script="unmount_server.sh",
                    args=['{:02}'.format(i), config.server_dir],
                    action_msg="Unmounting server {:02}".format(i))

@cli.command()
@pass_config
def remount(config):
    for i in range(config.start_at, config.start_at + config.num_servers):
        _run_script(script="remount_server.sh",
                    args=['{:02}'.format(i), config.server_dir],
                    action_msg="Remounting server {:02}".format(i))

<commit_msg>setup included<commit_after>import os
import stat
import subprocess
import click
import requests

script_folder="./scripts"
lgsm_dl_url="https://gameservermanagers.com/dl/linuxgsm.sh"

def _run_script(script="", path=None, args=(), action_msg=""):
    click.echo(action_msg)
    if not path:
        path = os.path.join(script_folder, script)
    try:
        subprocess.run([path, *args], shell=True, check=True)
    except subprocess.CalledProcessError as e:
        click.echo(e)

class InstanceConfig(object):
    def __init__(self):
        self.servers = None
        self.start_at = None
        self.outdir = None

pass_instance_config = click.make_pass_decorator(InstanceConfig, ensure=True)

@click.group()
def cli():
    pass

@cli.command()
@click.option('--dir', type=click.Path(), default='./rootserver')
@click.option('--install', is_flag=True)
def setup_root(dir, install):
    os.makedirs(dir, exist_ok=True)
    lgsm_script_path = os.path.join(dir, 'linuxgsm.sh')
    lgsm_script = requests.get(lgsm_dl_url, stream=True)
    with open(lgsm_script_path, 'wb') as f:
        for chunk in lgsm_script.iter_content(chunk_size=1024):
            if chunk:
                f.write(chunk)
    st = os.stat(lgsm_script_path)
    os.chmod(lgsm_script_path, st.st_mode | stat.S_IEXEC)
    _run_script(path=lgsm_script_path,
                args=['csgoserver'])
    if install:
        csgoserver_script_path = os.path.join(dir, 'csgoserver.sh')
        _run_script(path=csgoserver_script_path,
                    args=['auto-install'],
                    action_msg="INSTALLING CSGO")

@cli.group()
@click.option('--num-servers', default=8)
@click.option('--start-at', default=1)
@click.option('--server-dir', type=click.Path(), default='./servers')
@pass_instance_config
def instances(config, num_servers, start_at, server_dir):
    config.num_servers = num_servers
    config.start_at = start_at
    config.server_dir = server_dir

@instances.command()
@pass_instance_config
def scaffold(config):
    for i in range(config.start_at, config.start_at + config.num_servers):
        os.makedirs(os.path.join(config.server_dir, '{:02}'.format(i)))
        os.makedirs(os.path.join(config.server_dir, '.{:02}'.format(i), 'upper'))
        os.makedirs(os.path.join(config.server_dir, '.{:02}'.format(i), 'work'))

@instances.command()
@click.option('--root-dir', type=click.Path(), default='./rootserver')
@pass_instance_config
def mount(config, root_dir):
    for i in range(config.start_at, config.start_at + config.num_servers):
        _run_script(script="mount_server.sh",
                    args=['{:02}'.format(i), root_dir, config.server_dir],
                    action_msg="Mounting server {:02}".format(i))

@instances.command()
@pass_instance_config
def unmount(config):
    for i in range(config.start_at, config.start_at + config.num_servers):
        _run_script(script="unmount_server.sh",
                    args=['{:02}'.format(i), config.server_dir],
                    action_msg="Unmounting server {:02}".format(i))

@instances.command()
@pass_instance_config
def remount(config):
    for i in range(config.start_at, config.start_at + config.num_servers):
        _run_script(script="remount_server.sh",
                    args=['{:02}'.format(i), config.server_dir],
                    action_msg="Remounting server {:02}".format(i))

<|endoftext|>


<commit_before># coding=utf-8

import random
from os.path import join
from re import match
from sys import version_info

import requests_cache
from appdirs import user_cache_dir
from requests.adapters import HTTPAdapter

from mapi import log
from mapi.compatibility import ustr

__all__ = [
    "AGENT_CHROME",
    "AGENT_EDGE",
    "AGENT_IOS",
    "AGENT_ALL",
    "CACHE_PATH",
    "clear_cache",
    "clean_dict",
    "d2l",
    "get_session",
    "get_user_agent",
    "request_json",
]

AGENT_CHROME = (
    "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_1 like Mac OS X) AppleWebKit/601.1"
    " (KHTML, like Gecko) CriOS/53.0.2785.86 Mobile/14A403 Safari/601.1.46"
)
AGENT_EDGE = (
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like "
    "Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393"
)
AGENT_IOS = (
    "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_1 like Mac OS X) "
    "AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/14A403 "
    "Safari/602.1"
)
AGENT_ALL = (AGENT_CHROME, AGENT_EDGE, AGENT_IOS)
CACHE_PATH = join(user_cache_dir(), "mapi-py%d.sqlite" % version_info.major)

def clear_cache():
    """ Clears requests-cache cache
    """
    get_session().cache.clear()

def clean_dict(target_dict, whitelist=None):
    """ Convenience function that removes a dicts keys that have falsy values
    """
    assert isinstance(target_dict, dict)
    return {
        ustr(k).strip(): ustr(v).strip()
        for k, v in target_dict.items()
        if v not in (None, Ellipsis, [], (), "")
        and (not whitelist or k in whitelist)
    }

def d2l(d):
    """ Convenience function that converts a dict into a sorted list of tuples
    """
    return sorted([(k, v) for k, v in d.items()])

def get_session():
    """ Convenience function that returns request-cache session singleton
    """
    if not hasattr(get_session, "session"):
        get_session.session = requests_cache.CachedSession(
            cache_name=CACHE_PATH.rstrip(".sqlite"),
            expire_after=518400,  # 6 days
        )
        adapter = HTTPAdapter(max_retries=3)
        get_session.session.mount("http://", adapter)
        get_session.session.mount("https://", adapter)
    return get_session.session

def get_user_agent(platform=None):
    """ Convenience function that looks up a user agent string, random if N/A
    """
    if isinstance(platform, ustr):
        platform = platform.upper()
    return {"chrome": AGENT_CHROME, "edge": AGENT_EDGE, "ios": AGENT_IOS}.get(
        platform, random.choice(AGENT_ALL)
    )

def request_json(
    url, parameters=None, body=None, headers=None, cache=True, agent=None
):
    """ Queries a url for json data

    Note: Requests are cached using requests_cached for a week, this is done
    transparently by using the package's monkey patching
    """
    assert url
    content = None
    status = 500
    session = get_session()

    log.info("-" * 80)
    log.info("url: %s", url)

    if isinstance(headers, dict):
        headers = clean_dict(headers)
    else:
        headers = dict()
    if isinstance(parameters, dict):
        parameters = d2l(clean_dict(parameters))
    if body:
        method = "POST"
        headers["content-type"] = "application/json"
        headers["user-agent"] = get_user_agent(agent)
        headers["content-length"] = ustr(len(body))
    else:
        method = "GET"
        headers["user-agent"] = get_user_agent(agent)

    initial_cache_state = session._is_cache_disabled  # yes, i'm a bad person
    try:
        session._is_cache_disabled = not cache
        response = session.request(
            url=url,
            params=parameters,
            json=body,
            headers=headers,
            method=method,
            timeout=1,
        )
        status = response.status_code
        content = response.json() if status // 100 == 2 else None
        cache = getattr(response, "from_cache", False)
    except Exception as e:
        status = 500
        content = None
        log.debug(e, exc_info=True)
    else:
        log.debug("method: %s", method)
        log.debug("headers: %r", headers)
        log.debug("parameters: %r", parameters)
        log.debug("cache: %r", cache)
        log.info("status: %d", status)
        log.debug("content: %s", content)
    finally:
        session._is_cache_disabled = initial_cache_state
    return status, content

def year_expand(s):
    """ Parses a year or dash-delimited year range
    """
    regex = r"^((?:19|20)\d{2})?(\s*-\s*)?((?:19|20)\d{2})?$"
    try:
        start, dash, end = match(regex, ustr(s)).groups()
        start = start or 1900
        end = end or 2099
    except AttributeError:
        return 1900, 2099
    return (int(start), int(end)) if dash else (int(start), int(start))
<commit_msg>Documents utils module<commit_after># coding=utf-8

""" A collection of utility functions non-specific to mapi's domain logic
"""

import random
from os.path import join
from re import match
from sys import version_info

import requests_cache
from appdirs import user_cache_dir
from requests.adapters import HTTPAdapter

from mapi import log
from mapi.compatibility import ustr

__all__ = [
    "AGENT_CHROME",
    "AGENT_EDGE",
    "AGENT_IOS",
    "AGENT_ALL",
    "CACHE_PATH",
    "clear_cache",
    "clean_dict",
    "d2l",
    "get_session",
    "get_user_agent",
    "request_json",
]

AGENT_CHROME = (
    "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_1 like Mac OS X) AppleWebKit/601.1"
    " (KHTML, like Gecko) CriOS/53.0.2785.86 Mobile/14A403 Safari/601.1.46"
)
AGENT_EDGE = (
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like "
    "Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393"
)
AGENT_IOS = (
    "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_1 like Mac OS X) "
    "AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/14A403 "
    "Safari/602.1"
)
AGENT_ALL = (AGENT_CHROME, AGENT_EDGE, AGENT_IOS)
CACHE_PATH = join(user_cache_dir(), "mapi-py%d.sqlite" % version_info.major)

def clear_cache():
    """ Clears requests-cache cache
    """
    get_session().cache.clear()

def clean_dict(target_dict, whitelist=None):
    """ Convenience function that removes a dicts keys that have falsy values
    """
    assert isinstance(target_dict, dict)
    return {
        ustr(k).strip(): ustr(v).strip()
        for k, v in target_dict.items()
        if v not in (None, Ellipsis, [], (), "")
        and (not whitelist or k in whitelist)
    }

def d2l(d):
    """ Convenience function that converts a dict into a sorted list of tuples
    """
    return sorted([(k, v) for k, v in d.items()])

def get_session():
    """ Convenience function that returns request-cache session singleton
    """
    if not hasattr(get_session, "session"):
        get_session.session = requests_cache.CachedSession(
            cache_name=CACHE_PATH.rstrip(".sqlite"),
            expire_after=518400,  # 6 days
        )
        adapter = HTTPAdapter(max_retries=3)
        get_session.session.mount("http://", adapter)
        get_session.session.mount("https://", adapter)
    return get_session.session

def get_user_agent(platform=None):
    """ Convenience function that looks up a user agent string, random if N/A
    """
    if isinstance(platform, ustr):
        platform = platform.upper()
    return {"chrome": AGENT_CHROME, "edge": AGENT_EDGE, "ios": AGENT_IOS}.get(
        platform, random.choice(AGENT_ALL)
    )

def request_json(
    url, parameters=None, body=None, headers=None, cache=True, agent=None
):
    """ Queries a url for json data

    Note: Requests are cached using requests_cached for a week, this is done
    transparently by using the package's monkey patching
    """
    assert url
    content = None
    status = 500
    session = get_session()

    log.info("-" * 80)
    log.info("url: %s", url)

    if isinstance(headers, dict):
        headers = clean_dict(headers)
    else:
        headers = dict()
    if isinstance(parameters, dict):
        parameters = d2l(clean_dict(parameters))
    if body:
        method = "POST"
        headers["content-type"] = "application/json"
        headers["user-agent"] = get_user_agent(agent)
        headers["content-length"] = ustr(len(body))
    else:
        method = "GET"
        headers["user-agent"] = get_user_agent(agent)

    initial_cache_state = session._is_cache_disabled  # yes, i'm a bad person
    try:
        session._is_cache_disabled = not cache
        response = session.request(
            url=url,
            params=parameters,
            json=body,
            headers=headers,
            method=method,
            timeout=1,
        )
        status = response.status_code
        content = response.json() if status // 100 == 2 else None
        cache = getattr(response, "from_cache", False)
    except Exception as e:
        log.debug(e, exc_info=True)
    else:
        log.debug("method: %s", method)
        log.debug("headers: %r", headers)
        log.debug("parameters: %r", parameters)
        log.debug("cache: %r", cache)
        log.info("status: %d", status)
        log.debug("content: %s", content)
    finally:
        session._is_cache_disabled = initial_cache_state
    return status, content

def year_expand(s):
    """ Parses a year or dash-delimited year range
    """
    regex = r"^((?:19|20)\d{2})?(\s*-\s*)?((?:19|20)\d{2})?$"
    try:
        start, dash, end = match(regex, ustr(s)).groups()
        start = start or 1900
        end = end or 2099
    except AttributeError:
        return 1900, 2099
    return (int(start), int(end)) if dash else (int(start), int(start))
<|endoftext|>


<commit_before>from tokens.token import Token
from tokens.variable import Variable

class Expression(Token):
    """Expressions should be grouped (more can be combined by combining expressions, e.g. (token -> expr)).
       Order of tokens is not taken into account, and results are undefined if relied upon."""

    def __init__(self):
        super().__init__(operands=0)
        self.tokens = []

    def add_token(self, token):
        self.tokens.append(token)

    def get_variables(self):
        variables = set()

        for t in self.tokens:
            if isinstance(t, Expression):
                variables |= t.get_variables()
            elif isinstance(t, Variable):
                variables.add(t.representation)

        return variables

    def apply(self, solutions):
        # Solutions is a dict containing variable: True/False
        for i in range(len(self.tokens)):
            ct = self.tokens[i]
            if ct.operands == 1:
                # Assume next token takes no operands or it would not be well formed…
                nt = self.tokens[i+1]
                return ct.apply(nt.apply(solutions))

            elif ct.operands == 2:
                # Assume previous and next tokens take no operands or it would not be well formed…
                pt = self.tokens[i-1]
                nt = self.tokens[i+1]
                return ct.apply(pt.apply(solutions), nt.apply(solutions))

        # This expression should only have 1 token or it would not be well-formed…
        return self.tokens[0].apply()

    @staticmethod
    def _binary_digit(decimal, index_from_right):
        # index_from_right is 0 based
        half = 2 ** index_from_right  # half of power
        power = half * 2  # power of 2
        return decimal % power < half

    def find_solutions(self):
        variables = list(self.get_variables())
        variables.sort()

        solutions = []

        for i in range(2**len(variables)):
            solution = {}
            for j in range(len(variables)):
                # To follow the order of powers of two, one should start with the
                # highest (len(variables) - j - 1) and then go down, but since
                # order doesn't really matter, just use j as the index_from_right
                solution[variables[j]] = self._binary_digit(i, j)

            if self.apply(solution):
                solutions.append(solution)

        return solutions

    def __repr__(self):
        return '(' + ' '.join(repr(t) for t in self.tokens) + ')'
<commit_msg>Improve _binary_digit<commit_after>from tokens.token import Token
from tokens.variable import Variable

class Expression(Token):
    """Expressions should be grouped (more can be combined by combining expressions, e.g. (token -> expr)).
       Order of tokens is not taken into account, and results are undefined if relied upon."""

    def __init__(self):
        super().__init__(operands=0)
        self.tokens = []

    def add_token(self, token):
        self.tokens.append(token)

    def get_variables(self):
        variables = set()

        for t in self.tokens:
            if isinstance(t, Expression):
                variables |= t.get_variables()
            elif isinstance(t, Variable):
                variables.add(t.representation)

        return variables

    def apply(self, solutions):
        # Solutions is a dict containing variable: True/False
        for i in range(len(self.tokens)):
            ct = self.tokens[i]
            if ct.operands == 1:
                # Assume next token takes no operands or it would not be well formed…
                nt = self.tokens[i+1]
                return ct.apply(nt.apply(solutions))

            elif ct.operands == 2:
                # Assume previous and next tokens take no operands or it would not be well formed…
                pt = self.tokens[i-1]
                nt = self.tokens[i+1]
                return ct.apply(pt.apply(solutions), nt.apply(solutions))

        # This expression should only have 1 token or it would not be well-formed…
        return self.tokens[0].apply()

    @staticmethod
    def _binary_digit(decimal, index_from_right):
        # index_from_right is 0 based
        return (decimal >> index_from_right) & 1

    def find_solutions(self):
        variables = list(self.get_variables())
        variables.sort()

        solutions = []

        for i in range(2**len(variables)):
            solution = {}
            for j in range(len(variables)):
                # To follow the order of powers of two, one should start with the
                # highest (len(variables) - j - 1) and then go down, but since
                # order doesn't really matter, just use j as the index_from_right
                solution[variables[j]] = self._binary_digit(i, j)

            if self.apply(solution):
                solutions.append(solution)

        return solutions

    def __repr__(self):
        return '(' + ' '.join(repr(t) for t in self.tokens) + ')'
<|endoftext|>