psyced/world/drivers/pike/include/interface.h

152 lines
5.3 KiB
C

// $Id: interface.h,v 1.32 2008/04/18 13:34:38 lynx Exp $ // vim:syntax=lpc:ts=8
// several things in here do not look like they were optimized for pike.. TODO
#define _INCLUDE_INTERFACE_H
#define DRIVER_VERSION ("pike/"+ __VERSION__)
// driver abstraction kit -- abstraction layer from driver details
// [-1] vs [<1] syntax kludge
#define char_from_end(WHAT, NUMBER) WHAT[- NUMBER]
#define slice_from_end(WHAT,FROM,TO) WHAT[FROM .. sizeof(WHAT)-TO]
// pike also provides search() says eMBee....
#define abbrev(SMALL, BIG) (SMALL == BIG[0..sizeof(SMALL)-1])
#define trail(SMALL, BIG) (SMALL == BIG[sizeof(BIG)-sizeof(SMALL) ..])
// is it this simple? let's try
#define strstr search
#define raise_error(ERROR) throw(ERROR)
#define shutdown() exit(0)
#define clone_object(XXX) XXX()
#define named_clone(XXX, NAME) XXX()->sName(NAME)
#define file_name(OBJECT) to_string(OBJECT)
#define copy(WHATEVER) copy_value(WHATEVER)
#define find_object(XXX) ((object) XXX)
#define m_indices indices
#define m_values values
// generic string replacer
//#define replace(s, o, n) implode(explode(s, o), n)
// exists as a system function in pike with exact same arguments, phew!
// backward compat -- useful when writing multi-driver code
#define prereplace(s) (s)
#define postreplace(s) (s)
// let's use index() for strings and arrays
// to avoid confusion with mapping-member semantics
//
#define index(STRING, CHAR) member(STRING, CHAR)
#define rindex(STRING, CHAR) rmember(STRING, CHAR)
//
// but pike doesn't have member, it's called has_index()
// we keep on using index() and member() in all languages
#define member(HAYSTACK, NEEDLE) has_index(HAYSTACK, NEEDLE)
// you might also want to have a look on has_value(). well. maybe not.
// strlen() is obsolet/deprecated in pike, sizeof() is suggested.
// well, i suggest we keep on using strlen() for strings, as we never know what
// other languages are popping up that psyced has to be ported to.
#define strlen(str) sizeof(str)
// pike doesn't know previous_object. but we can emulate it.
#define previous_object() function_object(backtrace()[-2][2])
// compare strings ignoring case
#define stricmp(one, two) (lower_case(one) != lower_case(two))
// implode & explode are operator operations in pike.
#define implode(what, with) ((what) * (with))
#define explode(what, with) ((what) / (with))
// brilliant. exactly the same interface. saga did a good job! :)
#define dns_resolve Protocols.DNS.async_host_to_ip
#define dns_rresolve Protocols.DNS.async_ip_to_host
// this is useless really, since programs will never run as objects (?)
//#define clonep(ob) (!programp(ob))
// so we have to rewrite some stuff..
// none of our objects supports isClone()
// this is just a first approach to the problem
#define clonep(ob) (ob->isClone())
// all of this object naming stuff won't work unless we name our clones
// at creation time.. so plenty to be done here
//
// to_string behaves differently with ldmud.. sigh
#define o2s(any) ((objectp(any)?"/":"")+sprintf("%O",any))
// object to http URL (without http://host:port) conversion macros
#define object2url(ob) replace( stringp(ob)?ob:("/"+sprintf("%O",ob)), "#", "," )
#define url2object(ob) replace( ob, ",", "#" )
// nosave? static? volatile. no idea if pike has something like this
#define volatile static
// every lpc dialect has its own foreach syntax. aint that cute?
#define each(ITEM, LIST) foreach(LIST; ; ITEM)
#define mapeach(KEY, VALUE, MAPPING) foreach(MAPPING; KEY; VALUE)
#define pointerp arrayp
// thoughts on closures in lpc and pike.
//
// the new context closure syntax of ldmud looks either like this:
// int x=5;
// closure cl = function int : (int x) { return x++; };
//
// or even mudossish like this:
// int x=5;
// closure cl = (: return x++; :);
//
// while this is pike instead:
// int x=5;
// function factory(int y) { return lambda() { return y++; }; };
// function cl = factory(x);
//
// are you sure we cannot return a function without naming it factory first?
#define CLOSURE(args, tcontext, context, code) lambda tcontext { return lambda args code; } context
// typical usage:
// int x=5;
// function f = CLOSURE((int y), (int x), (x), { return x * y; });
#define virtual
#define closure function
// pike's varargs syntax requires me to do some tricks here
#define varargs
#define vaclosure function|void
#define vamapping mapping|void
#define vaobject object|void
#define vastring string|void
#define vamixed mixed|void
#define vaint int|void
#define to_string(XXX) ((string) XXX)
#define to_int(XXX) ((int) XXX)
// ... this stuff may want to be done in a more pikey way
// extracts hh:mm:ss format from ctime output
#define hhmmss(CTIME) CTIME[11..18]
// extracts hh:mm format from ctime output (for idle times)
#define hhmm(CTIME) CTIME[11..15]
// typical timestamp string: hhmm or iso-date if older than 24 hours
#define time_or_date(TS) \
(time() - TS > 24*60*60 ? isotime(TS, 0) : hhmm(ctime( TS )))
// TODO *** stuff that needs to be solved better *** //
#define interactive(ME) ME
//#define find_service(NAME) 0
//#define find_person(NAME) find_object(NAME)
#define query_udp_port() 4404
#define T(METHODTODO, DEFAULTTEXT) DEFAULTTEXT
#define OSTYPE "TODO"
#define MACHTYPE "TODO"
// leaving out a number here crashes pike.. amazing
#define DEBUG 1
#define DEVELOPMENT