diff --git a/core/logic/DebugReporter.cpp b/core/logic/DebugReporter.cpp index 5c5be839..4d733b5f 100644 --- a/core/logic/DebugReporter.cpp +++ b/core/logic/DebugReporter.cpp @@ -69,13 +69,13 @@ void DebugReport::GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err, ke::SafeVsprintf(buffer, sizeof(buffer), message, ap); const char *plname = pluginsys->FindPluginByContext(ctx->GetContext())->GetFilename(); - const char *error = g_pSourcePawn2->GetErrorString(err); - if (error) - { - g_Logger.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error); - } else { - g_Logger.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err); + if (err >= 0) { + const char *error = g_pSourcePawn2->GetErrorString(err); + if (error) + g_Logger.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error); + else + g_Logger.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err); } g_Logger.LogError("[SM] %s", buffer); diff --git a/core/logic/DebugReporter.h b/core/logic/DebugReporter.h index 27b54a9b..e79b8932 100644 --- a/core/logic/DebugReporter.h +++ b/core/logic/DebugReporter.h @@ -47,6 +47,8 @@ public: // IDebugListener void ReportError(const IErrorReport &report, IFrameIterator &iter); void OnDebugSpew(const char *msg, ...); public: + // If err is -1, caller assumes the automatic reporting by SourcePawn is + // good enough, and only wants the supplemental logging provided here. void GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...); void GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err, const char *message, va_list ap); void GenerateCodeError(IPluginContext *ctx, uint32_t code_addr, int err, const char *message, ...); diff --git a/core/logic/smn_menus.cpp b/core/logic/smn_menus.cpp index 40926ab2..c44d0970 100644 --- a/core/logic/smn_menus.cpp +++ b/core/logic/smn_menus.cpp @@ -496,96 +496,47 @@ void CMenuHandler::OnMenuVoteResults(IBaseMenu *menu, const menu_vote_result_t * } IPluginContext *pContext = m_pVoteResults->GetParentContext(); - bool no_call = false; - int err; + AutoEnterHeapScope heap_scope(pContext); /* First array */ cell_t client_array_address = -1; - cell_t *client_array_base = NULL; - cell_t client_array_size = results->num_clients + (results->num_clients * 2); - if (client_array_size) - { - if ((err = pContext->HeapAlloc(client_array_size, &client_array_address, &client_array_base)) - != SP_ERROR_NONE) - { - g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for client list.", client_array_size * sizeof(cell_t)); - no_call = true; - } else { - cell_t target_offs = sizeof(cell_t) * results->num_clients; - cell_t *cur_index = client_array_base; - cell_t *cur_array; - for (unsigned int i=0; inum_clients; i++) - { - /* Copy the array index */ - *cur_index = target_offs; - /* Get the current array address */ - cur_array = (cell_t *)((char *)cur_index + target_offs); - /* Store information */ - cur_array[0] = results->client_list[i].client; - cur_array[1] = results->client_list[i].item; - /* Adjust for the new target by subtracting one indirection - * and adding one array. - */ - target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t); - cur_index++; - } + if (cell_t client_array_size = results->num_clients * 2) { + auto init = std::make_unique(client_array_size); + for (unsigned int i = 0; i < results->num_clients; i++) { + init[i * 2] = results->client_list[i].client; + init[i * 2 + 1] = results->client_list[i].item; + } + + if (!pContext->HeapAlloc2dArray(results->num_clients, 2, &client_array_address, init.get())) { + g_DbgReporter.GenerateError(pContext, m_fnVoteResult, -1, + "Menu callback could not allocate cells for client list."); + return; } } /* Second array */ cell_t item_array_address = -1; - cell_t *item_array_base = NULL; - cell_t item_array_size = results->num_items + (results->num_items * 2); - if (item_array_size) - { - if ((err = pContext->HeapAlloc(item_array_size, &item_array_address, &item_array_base)) - != SP_ERROR_NONE) - { - g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for item list.", item_array_size); - no_call = true; - } else { - cell_t target_offs = sizeof(cell_t) * results->num_items; - cell_t *cur_index = item_array_base; - cell_t *cur_array; - for (unsigned int i=0; inum_items; i++) - { - /* Copy the array index */ - *cur_index = target_offs; - /* Get the current array address */ - cur_array = (cell_t *)((char *)cur_index + target_offs); - /* Store information */ - cur_array[0] = results->item_list[i].item; - cur_array[1] = results->item_list[i].count; - /* Adjust for the new target by subtracting one indirection - * and adding one array. - */ - target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t); - cur_index++; - } + if (cell_t item_array_size = results->num_items * 2) { + auto init = std::make_unique(item_array_size); + for (unsigned int i = 0; i < results->num_items; i++) { + init[i * 2] = results->item_list[i].item; + init[i * 2 + 1] = results->item_list[i].count; + } + if (!pContext->HeapAlloc2dArray(results->num_items, 2, &item_array_address, init.get())) { + g_DbgReporter.GenerateError(pContext, m_fnVoteResult, -1, + "Menu callback could not allocate %d cells for item list.", + item_array_size); + return; } } - /* Finally, push everything */ - if (!no_call) - { - m_pVoteResults->PushCell(menu->GetHandle()); - m_pVoteResults->PushCell(results->num_votes); - m_pVoteResults->PushCell(results->num_clients); - m_pVoteResults->PushCell(client_array_address); - m_pVoteResults->PushCell(results->num_items); - m_pVoteResults->PushCell(item_array_address); - m_pVoteResults->Execute(NULL); - } - - /* Free what we allocated, in reverse order as required */ - if (item_array_address != -1) - { - pContext->HeapPop(item_array_address); - } - if (client_array_address != -1) - { - pContext->HeapPop(client_array_address); - } + m_pVoteResults->PushCell(menu->GetHandle()); + m_pVoteResults->PushCell(results->num_votes); + m_pVoteResults->PushCell(results->num_clients); + m_pVoteResults->PushCell(client_array_address); + m_pVoteResults->PushCell(results->num_items); + m_pVoteResults->PushCell(item_array_address); + m_pVoteResults->Execute(NULL); } bool CMenuHandler::OnSetHandlerOption(const char *option, const void *data) diff --git a/sourcepawn b/sourcepawn index 385d304e..7cb5bede 160000 --- a/sourcepawn +++ b/sourcepawn @@ -1 +1 @@ -Subproject commit 385d304ea81f1a2484b9638b275387b1e10efce2 +Subproject commit 7cb5bede74c184b9b1de4dbf6b0bfc2d23c4a17e