THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 10/07/2012 at 12:27, xxxxxxxx wrote:
@spedler: Thanks for your answer. I just got curious because I haven't seen it that way, yet. And I thought it may be just an issue of mine and I just did something wrone while getting the values.
Nevermind, here's a little code that implements a very very small printf() function in COFFEE. :)
// coding: utf-8
// author: Niklas Rosenstein
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// 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 General Public License for more details.
#include <c4d/c4d.h>
Bool RegisterCoffeeExtensions();
// COFFEE Extension Functions
void CoffeeExtension_printf(Coffee* engine, VALUE*& argv, LONG argc);
// coding: utf-8
// author: Niklas Rosenstein
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>
#include "coffeeext.h"
#include <stdio.h>
#include <c4d/c4d.h>
static String VALUEToString(VALUE* val, Bool& success);
Bool RegisterCoffeeExtensions() {
Coffee* engine = GetCoffeeMaster();
if (!engine) {
return FALSE;
}
engine->AddGlobalFunction("printf", CoffeeExtension_printf);
return TRUE;
}
void CoffeeExtension_printf(Coffee* engine, VALUE*& argv, LONG argc) {
// The function accepts at least one argument. The first argument should
// be string formatted like C-style printf. All following arguments
// will be inserted into the string.
// Possible format sequences are:
//
// %s: String
// %%: Escape for Percent character.
if (argc < 1) {
engine->SetError(COFFEEERROR_ARGW, "Expected at least one argument.");
goto nil;
}
// Somehow, the passed arguments are in reverse order.. -.-
VALUE* vformat = argv + argc - 1;
if (!vformat->IsType(DT_STRING)) {
engine->SetError(COFFEEERROR_BTYP, "Expected first argument to be string.");
goto nil;
}
goto continue_;
nil:
// Coffee-Return nil.
argv[argc].SetLong(0);
argv += argc;
return;
continue_:
char buffer[80];
String format = vformat->GetString();
LONG format_length = format.GetLength();
String destination = "";
int curr_arg = argc - 2;
VALUE* curr_val = NULL;
for (int i=0; i < format_length; i++) {
char character = format[i];
if (character == '%') {
i++;
if (!(i < format_length)) {
destination += String("%");
goto nil;
}
char fmt = format[i];
if (fmt == '%') {
destination += "%";
}
else {
curr_val = &argv[curr_arg];
Bool success;
if (fmt == 's') {
destination += VALUEToString(curr_val, success);
}
else {
sprintf(buffer, "Unsupported format character %c!", fmt);
engine->SetError(COFFEEERROR_BTYP, String(buffer));
goto nil;
}
curr_arg--;
}
}
else {
destination += String(1, format[i]);
}
}
GePrint(destination);
argv[argc].SetLong(1);
argv += argc;
return;
}
static String VALUEToString(VALUE* val, Bool& success) {
LONG type = val->GetType();
success = TRUE;
Vector v;
char buffer[20];
String final;
LONG count;
switch (type) {
case DT_NIL:
return String("nil");
case DT_LONG:
return LongToString(val->GetLong());
case DT_FLOAT:
return RealToString(val->GetReal());
case DT_VECTOR:
v = val->GetVector();
return "Vector(" + RealToString(v.x) + ", " + RealToString(v.y) +
", " + RealToString(v.z) + ")";
case DT_VOID:
sprintf(buffer, "0x%x", val->GetVoid());
return "[VOID at " + String(buffer) + "]";
case DT_BYTES:
return "[BYTES]";
case DT_STRING:
return val->GetString();
case DT_CLASS:
return "[CLASS]";
case DT_OBJECT:
sprintf(buffer, "0x%x", val->GetObject());
return "[OBJECT at " + String(buffer) + "]";
case DT_ARRAY:
final = "[";
count = val->GetSize();
for (int i=0; i < count; i++) {
VALUE* subval = val->GetArrayMember(i);
final += VALUEToString(subval, success) + ", ";
if (!success) {
return String();
}
}
final += "]";
return final;
// case DT_NUMBER:
default:
success = FALSE;
return String();
}
}
-Nik