all repos — mgba @ 60ec3e0e9926da9a10771f164f5040359f077872

mGBA Game Boy Advance Emulator

src/debugger/cli-debugger-scripting.c (view raw)

  1/* Copyright (c) 2013-2020 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include <mgba/core/scripting.h>
  7#include <mgba-util/string.h>
  8#include <mgba-util/vfs.h>
  9
 10#include <mgba/debugger/debugger.h>
 11#include <mgba/internal/debugger/cli-debugger.h>
 12
 13static const char* CLIScriptEngineName(struct mScriptEngine*);
 14static bool CLIScriptEngineInit(struct mScriptEngine*, struct mScriptBridge*);
 15static void CLIScriptEngineDeinit(struct mScriptEngine*);
 16static bool CLIScriptEngineIsScript(struct mScriptEngine*, const char* name, struct VFile* vf);
 17static bool CLIScriptEngineLoadScript(struct mScriptEngine*, const char* name, struct VFile* vf);
 18static void CLIScriptEngineRun(struct mScriptEngine*);
 19static bool CLIScriptEngineLookupSymbol(struct mScriptEngine*, const char* name, int32_t* out);
 20static void CLIScriptDebuggerEntered(struct mScriptEngine*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*);
 21
 22struct CLIScriptStatement {
 23	char* command;
 24	size_t commandLen;
 25};
 26
 27DECLARE_VECTOR(CLIScript, struct CLIScriptStatement);
 28DEFINE_VECTOR(CLIScript, struct CLIScriptStatement);
 29
 30struct CLIScriptEngine {
 31	struct mScriptEngine d;
 32	struct mScriptBridge* sb;
 33	struct CLIScript script;
 34};
 35
 36static void CLIScriptEngineClear(struct CLIScriptEngine* engine) {
 37	size_t i = CLIScriptSize(&engine->script);
 38	while (i-- > 0) {
 39		struct CLIScriptStatement* statement = CLIScriptGetPointer(&engine->script, i);
 40		free(statement->command);
 41	}
 42	CLIScriptClear(&engine->script);
 43}
 44
 45struct CLIScriptEngine* CLICreateScriptEngine(void) {
 46	struct CLIScriptEngine* engine = malloc(sizeof(*engine));
 47	engine->d.name = CLIScriptEngineName;
 48	engine->d.init = CLIScriptEngineInit;
 49	engine->d.deinit = CLIScriptEngineDeinit;
 50	engine->d.isScript = CLIScriptEngineIsScript;
 51	engine->d.loadScript = CLIScriptEngineLoadScript;
 52	engine->d.run = CLIScriptEngineRun;
 53	engine->d.lookupSymbol = CLIScriptEngineLookupSymbol;
 54	engine->d.debuggerEntered = CLIScriptDebuggerEntered;
 55	engine->sb = NULL;
 56	return engine;
 57}
 58
 59void CLIDebuggerScriptEngineInstall(struct mScriptBridge* sb) {
 60	struct CLIScriptEngine* se = CLICreateScriptEngine();
 61	mScriptBridgeInstallEngine(sb, &se->d);
 62}
 63
 64const char* CLIScriptEngineName(struct mScriptEngine* se) {
 65	UNUSED(se);
 66	return "cli-debugger";
 67}
 68
 69bool CLIScriptEngineInit(struct mScriptEngine* se, struct mScriptBridge* sb) {
 70	struct CLIScriptEngine* engine = (struct CLIScriptEngine*) se;
 71	engine->sb = sb;
 72	CLIScriptInit(&engine->script, 0);
 73	return true;
 74}
 75
 76void CLIScriptEngineDeinit(struct mScriptEngine* se) {
 77	struct CLIScriptEngine* engine = (struct CLIScriptEngine*) se;
 78	CLIScriptEngineClear(engine);
 79	CLIScriptDeinit(&engine->script);
 80	free(se);
 81}
 82
 83bool CLIScriptEngineIsScript(struct mScriptEngine* se, const char* name, struct VFile* vf) {
 84	UNUSED(se);
 85	UNUSED(vf);
 86	return endswith(name, ".mrc");
 87}
 88
 89bool CLIScriptEngineLoadScript(struct mScriptEngine* se, const char* name, struct VFile* vf) {
 90	UNUSED(name);
 91	struct CLIScriptEngine* engine = (struct CLIScriptEngine*) se;
 92	char buffer[256];
 93	ssize_t size;
 94	CLIScriptEngineClear(engine);
 95	struct CLIScriptStatement* statement;
 96	while ((size = vf->readline(vf, buffer, sizeof(buffer))) > 0) {
 97		if (buffer[size - 1] == '\n') {
 98			--size;
 99		}
100		statement = CLIScriptAppend(&engine->script);
101		statement->command = strndup(buffer, size);
102		statement->commandLen = size;
103	}
104	return true;
105}
106
107void CLIScriptEngineRun(struct mScriptEngine* se) {
108	struct CLIScriptEngine* engine = (struct CLIScriptEngine*) se;
109	struct CLIDebugger* debugger = (struct CLIDebugger*) mScriptBridgeGetDebugger(engine->sb);
110	struct CLIScriptStatement* statement;
111	size_t statementCount = CLIScriptSize(&engine->script);
112	size_t i;
113	for (i = 0; i < statementCount; i++) {
114		statement = CLIScriptGetPointer(&engine->script, i);
115		CLIDebuggerRunCommand(debugger, statement->command, statement->commandLen);
116	}
117}
118
119bool CLIScriptEngineLookupSymbol(struct mScriptEngine* se, const char* name, int32_t* out) {
120	UNUSED(se);
121	UNUSED(name);
122	UNUSED(out);
123	return false;
124}
125
126void CLIScriptDebuggerEntered(struct mScriptEngine* se, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) {
127	UNUSED(reason);
128	UNUSED(info);
129	struct CLIScriptEngine* engine = (struct CLIScriptEngine*) se;
130
131	struct mDebugger* debugger = mScriptBridgeGetDebugger(engine->sb);
132	if (!debugger) {
133		return;
134	}
135
136	// TODO: CLIDebuggerEntered(reason, info);
137}