#include <stdlib.h> #include <string.h> #include <lua.h> #include <sys/time.h> #include <time.h> static void _my_strncat( char** buffer, int* bufferlen, const char * item, int itemlen ) { char *p; if( strlen(*buffer) + itemlen >= *bufferlen ) { *buffer = realloc( *buffer, (*bufferlen)+itemlen+1024 ); *bufferlen += itemlen+1024; } p=*buffer; while( *p ) { p++; } while( itemlen-- ) { *(p++) = *(item++); } *p=0; } #define safencat(X,L) _my_strncat( &buffer, &bufferlen, X, L ) #define safecat(X) safencat(X,strlen(X)) /* If we ever need more spaces than that, I'm a monkey's uncle */ static const char * SPACES = " "; #define nextloop ++Text; ++linelen; if( linelen == wrapwidth ) newline=1; continue static void _my_word_examine( const char * Text, int * len, int * important ) { const char *s=Text; *important = 0; *len = 0; while( *s && *s != ' ' ) { if( *s == '@' || *s == '/' ) *important=1; s++; } *len = s-Text; } #define EXAMINE_WORD _my_word_examine( Text, &w_len, &w_imp ) #define SPLIT_WORD w_len=wrapwidth-linelen; safencat(Text,w_len); Text+=w_len; newline=1; continue #define AVAIL_SPACE (wrapwidth-linelen) char * WordWrap( const char * Text, int Indent, const char * Prefix, const int wrapwidth, const int splitforce ) { static char * buffer = NULL; static int bufferlen = 0; int linelen = 0; int newline = 0; int w_len, w_imp, w_max;; if( buffer == NULL ) { buffer = (char*)(malloc( 1024 )); bufferlen=1024; } *buffer = 0; /* Handle special cases */ if( Indent != -1 ) { safencat( "\r", 1 ); } if( Prefix != NULL && *Prefix ) { safecat( Prefix ); safencat( " ", 1 ); } if( Indent == -1 ) { safecat( Text ); return buffer; } /* End of special cases */ if( strlen(Text) + strlen(buffer) <= wrapwidth ) { safecat (Text); return buffer; } /* Okay, we have to actually make an effort to wordwrap... */ w_max = wrapwidth-( ( Prefix?strlen( Prefix ):0 ) + Indent); linelen = strlen(buffer)-1; /* Start as we mean to go on... (minus the \r)*/ while( *Text ) { /* We have a char *Text */ if (newline) { /* Remove any waiting spaces */ { char * b = buffer; while( *b ) { ++b; } /* Scan to end of buffer */ while( *b == ' ' ) { --b; } /* Trim spaces */ *(b+1) = 0; /* Terminate it before the spaces */ } /* Skip any new spaces... */ while( *Text && *Text == ' ' ) { ++Text; } if( *Text == 0 ) { /* We ran out of input trying to find the next starter */ /* Therefore we skip this newline and break... */ break; } safencat( "\n\r", 2 ); /* Lines appear to have to start with \r */ if( Prefix != NULL && *Prefix) safecat( Prefix ); safencat( SPACES, Indent ); linelen = (Prefix?strlen(Prefix):0)+Indent; newline = 0; continue; } if( *Text == ' ' || *Text == '\t' ) { safencat( Text, 1 ); nextloop; } /* It's a character we're interested in... speculate... */ EXAMINE_WORD; /* w_len is the words length, w_imp is its importance */ if( (w_len+linelen) <= wrapwidth ) { safencat( Text, w_len ); linelen += w_len; if( linelen == wrapwidth ) newline=1; Text += w_len; continue; } /* Okay, we can't fit the word on this line. */ if( w_len <= w_max ) { /* Can be fitted, without wrapping, on the next line. At what threshold do we consider this bad? */ if( (AVAIL_SPACE > splitforce) && !w_imp ) { /* Nope, we want to split... */ SPLIT_WORD; } /* We want to wrap the word, so set newline and return */ newline=1; continue; /* We're going to reconsider the word next time */ } /* word is more than a line's space big, decision time.. */ if( w_imp ) { /* word is 'important' so we want as much as possible together */ if (AVAIL_SPACE >= splitforce) { SPLIT_WORD; } newline=1; continue; } /* word is not important, and too big, so just split it */ SPLIT_WORD; } /* return -- regardless of the 'newline' settings */ return buffer; } /* char * WordWrap( const char * Text, int Indent, const char * Prefix ) */ int lua_wrap( lua_State *L ) { if( lua_gettop(L) < 5 ) { lua_error(L, "WordWrap(text,indent,prefix,wrapwidth,splitforce)" ); return 0; } if( ! lua_isstring(L, 1) ) { lua_error(L, "WordWrap(text,indent,prefix,wrapwidth,splitforce)" ); return 0; } if( ! lua_isnumber(L, 2) ) { lua_error(L, "WordWrap(text,indent,prefix,wrapwidth,splitforce)" ); return 0; } if( ! lua_isstring(L, 3) ) { lua_error(L, "WordWrap(text,indent,prefix,wrapwidth,splitforce)" ); return 0; } if( ! lua_isnumber(L, 4) ) { lua_error(L, "WordWrap(text,indent,prefix,wrapwidth,splitforce)" ); return 0; } if( ! lua_isnumber(L, 5) ) { lua_error(L, "WordWrap(text,indent,prefix,wrapwidth,splitforce)" ); return 0; } { const char * Text = lua_tostring(L, 1); const int Indent = (int)(lua_tonumber(L, 2)); const char * Prefix = lua_tostring(L, 3); const int wrapwidth = (int)(lua_tonumber(L,4)); const int splitforce = (int)(lua_tonumber(L,5)); char * wrapped = WordWrap( Text, Indent, Prefix, wrapwidth, splitforce ); lua_settop(L, 0); lua_pushstring(L, wrapped); return 1; } } int lua_epoch_time( lua_State *L ) { lua_settop(L, 0); lua_pushnumber(L, time( NULL ) ); return 1; } void wrap_register( lua_State *L ) { lua_pushcclosure( L, lua_wrap, 0 ); lua_setglobal( L, "WordWrap" ); lua_pushcclosure( L, lua_epoch_time, 0 ); lua_setglobal( L, "getSecs" ); }