Files
Krzosa Karol 44eb8be1db Improve API
2024-04-14 10:11:17 +02:00

57 lines
2.3 KiB
C++

void OnExprResolved_CheckPrintf(LC_AST *n, LC_Operand *op);
bool add_printf_format_check() {
bool result = false;
LC_Lang *lang = LC_LangAlloc();
lang->use_colored_terminal_output = UseColoredIO;
lang->breakpoint_on_error = BreakpointOnError;
lang->user_data = (void *)&result;
lang->on_expr_resolved = OnExprResolved_CheckPrintf;
lang->on_message = LC_IgnoreMessage;
LC_LangBegin(lang);
LC_RegisterPackageDir("../pkgs");
LC_RegisterPackageDir("../examples");
LC_Intern name = LC_ILit("add_printf_format_check");
LC_ParseAndResolve(name);
LC_LangEnd(lang);
return result;
}
void OnExprResolved_CheckPrintf(LC_AST *n, LC_Operand *op) {
if (n->kind == LC_ASTKind_ExprCall) {
LC_AST *name = n->ecompo.name;
if (name->kind == LC_ASTKind_ExprIdent) {
LC_Decl *decl = name->eident.resolved_decl;
if (decl->name == LC_ILit("printf")) {
LC_ResolvedCompo *items = n->ecompo.resolved_items;
LC_AST *string = items->first->expr;
IO_Assert(string->kind == LC_ASTKind_ExprString);
char *c = (char *)string->eatom.name;
LC_ResolvedCompoItem *item = items->first->next;
for (int i = 0; c[i]; i += 1) {
if (c[i] == '%') {
if (item == NULL) {
LC_ReportASTError(n, "too few arguments passed");
// Test reports success if error thrown correctly
*(bool *)L->user_data = true;
return;
}
if (c[i + 1] == 'd') {
if (item->expr->type != L->tint) LC_ReportASTError(item->expr, "expected int type");
item = item->next;
} else if (c[i + 1] == 's') {
if (item->expr->type != L->tpchar) LC_ReportASTError(item->expr, "expected *char type");
item = item->next;
}
}
}
if (item != NULL) LC_ReportASTError(item->expr, "too many arguments passed");
}
}
}
}