Exemplo n.º 1
0
def write_utf8_traceback_list(out, l):
    """
    Given the traceback list l, writes it to out as utf-8.
    """

    ul = [ ]

    for filename, line, what, text in l:

        # Filename is either unicode or an fsecoded string.
        if not isinstance(filename, six.text_type):
            filename = six.text_type(filename, FSENCODING, "replace")

        # Line is a number.

        # Assume what is in a unicode encoding, since it is either python,
        # or comes from inside Ren'Py.

        if isinstance(text, str):
            text = text.decode("utf-8", "replace")

        ul.append((filename, line, what, text))

    for t in traceback.format_list(ul):
        out.write(t.encode("utf-8", "replace"))
Exemplo n.º 2
0
    def safe_utf8(e):
        try:
            m = six.text_type(e)
        except:
            try:
                if len(e.args) == 0:
                    m = ""
                elif len(e.args) == 1:
                    m = e.args[0]
                else:
                    m = " ".join(e.args)
            except:
                try:
                    m = repr(e)
                except:
                    m = "<Could not encode exception.>"

        if isinstance(m, six.text_type):
            return m.encode("utf-8", "replace")
        else:
            return m
Exemplo n.º 3
0
 def __format__(self, spec):
     return format(six.text_type(self), spec)
Exemplo n.º 4
0
 def __str__(self):
     return six.text_type(self).encode("utf-8")
Exemplo n.º 5
0
def bootstrap(renpy_base):

    global renpy  # W0602

    import renpy.log  # @UnusedImport

    # Remove a legacy environment setting.
    if os.environ.get(b"SDL_VIDEODRIVER", "") == "windib":
        del os.environ[b"SDL_VIDEODRIVER"]

    renpy_base = six.text_type(renpy_base, FSENCODING, "replace")

    # If environment.txt exists, load it into the os.environ dictionary.
    if os.path.exists(renpy_base + "/environment.txt"):
        evars = {}
        with open(renpy_base + "/environment.txt", "rb") as f:
            code = compile(f.read(), renpy_base + "/environment.txt", 'exec')
            exec(code, evars)
        for k, v in six.iteritems(evars):
            if k not in os.environ:
                os.environ[k] = str(v)

    # Also look for it in an alternate path (the path that contains the
    # .app file.), if on a mac.
    alt_path = os.path.abspath("renpy_base")
    if ".app" in alt_path:
        alt_path = alt_path[:alt_path.find(".app") + 4]

        if os.path.exists(alt_path + "/environment.txt"):
            evars = {}
            with open(alt_path + "/environment.txt", "rb") as f:
                code = compile(f.read(), alt_path + "/environment.txt", 'exec')
                exec(code, evars)
            for k, v in six.iteritems(evars):
                if k not in os.environ:
                    os.environ[k] = str(v)

    # Get a working name for the game.
    name = os.path.basename(sys.argv[0])

    if name.find(".") != -1:
        name = name[:name.find(".")]

    # Parse the arguments.
    import renpy.arguments
    args = renpy.arguments.bootstrap()

    if args.trace:
        enable_trace(args.trace)

    if args.basedir:
        basedir = os.path.abspath(args.basedir).decode(FSENCODING)
    else:
        basedir = renpy_base

    if not os.path.exists(basedir):
        sys.stderr.write("Base directory %r does not exist. Giving up.\n" %
                         (basedir, ))
        sys.exit(1)

    gamedirs = [name]
    game_name = name

    while game_name:
        prefix = game_name[0]
        game_name = game_name[1:]

        if prefix == ' ' or prefix == '_':
            gamedirs.append(game_name)

    gamedirs.extend(['game', 'data', 'launcher/game'])

    for i in gamedirs:

        if i == "renpy":
            continue

        gamedir = basedir + "/" + i
        if os.path.isdir(gamedir):
            break
    else:
        gamedir = basedir

    sys.path.insert(0, basedir)

    if renpy.macintosh:
        # If we're on a mac, install our own os.start.
        os.startfile = mac_start

        # Are we starting from inside a mac app resources directory?
        if basedir.endswith("Contents/Resources/autorun"):
            renpy.macapp = True

    # Check that we have installed pygame properly. This also deals with
    # weird cases on Windows and Linux where we can't import modules. (On
    # windows ";" is a directory separator in PATH, so if it's in a parent
    # directory, we won't get the libraries in the PATH, and hence pygame
    # won't import.)
    try:
        import pygame_sdl2
        if not ("pygame" in sys.modules):
            pygame_sdl2.import_as_pygame()
    except:
        print("""\
Could not import pygame_sdl2. Please ensure that this program has been built
and unpacked properly. Also, make sure that the directories containing
this program do not contain : or ; in their names.

You may be using a system install of python. Please run {0}.sh,
{0}.exe, or {0}.app instead.
""".format(name),
              file=sys.stderr)

        raise

    # If we're not given a command, show the presplash.
    if args.command == "run" and not renpy.mobile:
        import renpy.display.presplash  # @Reimport
        renpy.display.presplash.start(basedir, gamedir)

    # Ditto for the Ren'Py module.
    try:
        import _renpy
        _renpy
    except:
        print("""\
Could not import _renpy. Please ensure that this program has been built
and unpacked properly.

You may be using a system install of python. Please run {0}.sh,
{0}.exe, or {0}.app instead.
""".format(name),
              file=sys.stderr)
        raise

    # Load up all of Ren'Py, in the right order.

    import renpy  # @Reimport
    renpy.import_all()

    renpy.loader.init_importer()

    exit_status = None

    try:
        while exit_status is None:
            exit_status = 1

            try:
                renpy.game.args = args
                renpy.config.renpy_base = renpy_base
                renpy.config.basedir = basedir
                renpy.config.gamedir = gamedir
                renpy.config.args = []

                if renpy.android:
                    renpy.config.logdir = os.environ['ANDROID_PUBLIC']
                else:
                    renpy.config.logdir = basedir

                if not os.path.exists(renpy.config.logdir):
                    os.makedirs(renpy.config.logdir, 0o777)

                renpy.main.main()

                exit_status = 0

            except KeyboardInterrupt:
                raise

            except renpy.game.UtterRestartException:

                # On an UtterRestart, reload Ren'Py.
                renpy.reload_all()

                exit_status = None

            except renpy.game.QuitException as e:
                exit_status = e.status

                if e.relaunch:
                    if hasattr(sys, "renpy_executable"):
                        subprocess.Popen([sys.renpy_executable] + sys.argv[1:])
                    else:
                        subprocess.Popen([sys.executable, "-EO"] + sys.argv)

            except renpy.game.ParseErrorException:
                pass

            except Exception as e:
                renpy.error.report_exception(e)
                pass

        sys.exit(exit_status)

    finally:

        if "RENPY_SHUTDOWN_TRACE" in os.environ:
            enable_trace(int(os.environ["RENPY_SHUTDOWN_TRACE"]))

        renpy.display.im.cache.quit()

        if renpy.display.draw:
            renpy.display.draw.quit()

        renpy.audio.audio.quit()

        # Prevent subprocess from throwing errors while trying to run it's
        # __del__ method during shutdown.
        if not renpy.emscripten:
            subprocess.Popen.__del__ = popen_del
Exemplo n.º 6
0
def add(msg, *args):
    if not msg in added:
        added[msg] = True
        msg = six.text_type(msg) % args
        print(msg.encode('utf-8'))
Exemplo n.º 7
0
def lint():
    """
    The master lint function, that's responsible for staging all of the
    other checks.
    """

    ap = renpy.arguments.ArgumentParser(description="Checks the script for errors and prints script statistics.", require_command=False)
    ap.add_argument("filename", nargs='?', action="store", help="The file to write to.")

    args = ap.parse_args()

    if args.filename:
        f = open(args.filename, "w")
        sys.stdout = f

    renpy.game.lint = True

    print(codecs.BOM_UTF8)
    print(six.text_type(renpy.version + " lint report, generated at: " + time.ctime()).encode("utf-8"))

    # This supports check_hide.
    global image_prefixes
    image_prefixes = { }

    for k in renpy.display.image.images:
        image_prefixes[k[0]] = True

    # Iterate through every statement in the program, processing
    # them. We sort them in filename, linenumber order.

    all_stmts = [ (i.filename, i.linenumber, i) for i in renpy.game.script.all_stmts ]
    all_stmts.sort()

    # The current count.
    counts = collections.defaultdict(Count)

    # The current language.
    language = None

    menu_count = 0
    screen_count = 0
    image_count = 0

    global report_node

    for _fn, _ln, node in all_stmts:
        if isinstance(node, (renpy.ast.Show, renpy.ast.Scene)):
            precheck_show(node)

    for _fn, _ln, node in all_stmts:

        if common(node):
            continue

        report_node = node

        if isinstance(node, renpy.ast.Image):
            image_count += 1
            check_image(node)

        elif isinstance(node, renpy.ast.Show):
            check_show(node, False)

        elif isinstance(node, renpy.ast.Scene):
            check_show(node, True)

        elif isinstance(node, renpy.ast.Hide):
            check_hide(node)

        elif isinstance(node, renpy.ast.With):
            check_with(node)

        elif isinstance(node, renpy.ast.Say):
            check_say(node)

            counts[language].add(node.what)

        elif isinstance(node, renpy.ast.Menu):
            check_menu(node)
            menu_count += 1

        elif isinstance(node, renpy.ast.Jump):
            check_jump(node)

        elif isinstance(node, renpy.ast.Call):
            check_call(node)

        elif isinstance(node, renpy.ast.While):
            check_while(node)

        elif isinstance(node, renpy.ast.If):
            check_if(node)

        elif isinstance(node, renpy.ast.UserStatement):
            check_user(node)

        elif isinstance(node, renpy.ast.Label):
            check_label(node)

        elif isinstance(node, renpy.ast.Translate):
            language = node.language

        elif isinstance(node, renpy.ast.EndTranslate):
            language = None

        elif isinstance(node, renpy.ast.Screen):
            screen_count += 1
            check_screen(node)

        elif isinstance(node, renpy.ast.Define):
            check_define(node, "define")

        elif isinstance(node, renpy.ast.Default):
            check_define(node, "default")

    report_node = None

    check_styles()
    check_filename_encodings()

    for f in renpy.config.lint_hooks:
        f()

    lines = [ ]

    def report_language(language):

        count = counts[language]

        if count.blocks <= 0:
            return

        if language is None:
            s = "The game"
        else:
            s = "The {0} translation".format(language)

        s += """ contains {0} dialogue blocks, containing {1} words
and {2} characters, for an average of {3:.1f} words and {4:.0f}
characters per block. """.format(
            humanize(count.blocks),
            humanize(count.words),
            humanize(count.characters),
            1.0 * count.words / count.blocks,
            1.0 * count.characters / count.blocks)

        lines.append(s)

    print()
    print()
    print("Statistics:")
    print()

    languages = list(counts)
    languages.sort()
    for i in languages:
        report_language(i)

    lines.append("The game contains {0} menus, {1} images, and {2} screens.".format(
        humanize(menu_count), humanize(image_count), humanize(screen_count)))

    for l in lines:
        for ll in textwrap.wrap(l, 78):
            print(ll.encode("utf-8"))

        print()

    for i in renpy.config.lint_stats_callbacks:
        i()

    print()
    if renpy.config.developer and (renpy.config.original_developer != "auto"):
        print("Remember to set config.developer to False before releasing.")
        print()

    print("Lint is not a substitute for thorough testing. Remember to update Ren'Py")
    print("before releasing. New releases fix bugs and improve compatibility.")

    return False