Newer
Older
/* js_global.c */
/* Synchronet JavaScript "global" object properties/methods for all servers */
/* $Id$ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html *
* *
* 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 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#define JS_THREADSAFE /* needed for JS_SetContextThread */
#include "md5.h"
#include "htmlansi.h"
#include "ini_file.h"
#define MAX_ANSI_SEQ 16
#define MAX_ANSI_PARAMS 8
/* Global Object Properites */
enum {
GLOB_PROP_ERRNO
,GLOB_PROP_ERRNO_STR
,GLOB_PROP_SOCKET_ERRNO
};
static JSBool js_system_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
jsint tiny;
tiny = JSVAL_TO_INT(id);
switch(tiny) {
case GLOB_PROP_SOCKET_ERRNO:
JS_NewNumberValue(cx,ERROR_VALUE,vp);
break;
case GLOB_PROP_ERRNO_STR:
if((js_str=JS_NewStringCopyZ(cx, strerror(errno)))==NULL)
return(JS_FALSE);
*vp = STRING_TO_JSVAL(js_str);
break;
#define GLOBOBJ_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED
static struct JSPropertySpec js_global_properties[] = {
/* name, tinyid, flags */
{ "errno" ,GLOB_PROP_ERRNO ,GLOBOBJ_FLAGS },
{ "errno_str" ,GLOB_PROP_ERRNO_STR ,GLOBOBJ_FLAGS },
{ "socket_errno" ,GLOB_PROP_SOCKET_ERRNO ,GLOBOBJ_FLAGS },
typedef struct {
JSRuntime* runtime;
JSContext* cx;
JSContext* parent_cx;
JSObject* obj;
JSScript* script;
msg_queue_t* msg_queue;
js_branch_t branch;
JSErrorReporter error_reporter;
} background_data_t;
static void background_thread(void* arg)
background_data_t* bg = (background_data_t*)arg;
jsval result=JSVAL_VOID;
jsval exit_code;
msgQueueAttach(bg->msg_queue);
JS_SetContextThread(bg->cx);
if(!JS_ExecuteScript(bg->cx, bg->obj, bg->script, &result)
&& JS_GetProperty(bg->cx, bg->obj, "exit_code", &exit_code))
result=exit_code;
js_enqueue_value(bg->cx, bg->msg_queue, result, NULL);
JS_DestroyScript(bg->cx, bg->script);
JS_DestroyContext(bg->cx);
JS_DestroyRuntime(bg->runtime);
free(bg);
}
static void
js_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
{
background_data_t* bg;
if((bg=(background_data_t*)JS_GetContextPrivate(cx))==NULL)
return;
/* Use parent's context private data */
JS_SetContextPrivate(cx, JS_GetContextPrivate(bg->parent_cx));
/* Call parent's error reporter */
bg->error_reporter(cx, message, report);
/* Restore our context private data */
JS_SetContextPrivate(cx, bg);
}
static JSBool js_BranchCallback(JSContext *cx, JSScript* script)
{
background_data_t* bg;
if((bg=(background_data_t*)JS_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
if(bg->parent_cx!=NULL && !JS_IsRunning(bg->parent_cx)) /* die when parent dies */
return(JS_FALSE);
return js_CommonBranchCallback(cx,&bg->branch);
static JSBool
js_load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char path[MAX_PATH+1];
uintN i;
const char* filename;
JSScript* script;
scfg_t* cfg;
JSObject* js_argv;
JSObject* exec_obj;
JSContext* exec_cx=cx;
JSBool success;
JSBool background=JS_FALSE;
*rval=JSVAL_VOID;
if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
exec_obj=JS_GetScopeChain(cx);
if(JSVAL_IS_BOOLEAN(argv[argn]))
background=JSVAL_TO_BOOLEAN(argv[argn++]);
if(background) {
if((bg=(background_data_t*)malloc(sizeof(background_data_t)))==NULL)
return(JS_FALSE);
memset(bg,0,sizeof(background_data_t));
/* Setup default values for branch settings */
bg->branch.limit=JAVASCRIPT_BRANCH_LIMIT;
bg->branch.gc_interval=JAVASCRIPT_GC_INTERVAL;
bg->branch.yield_interval=JAVASCRIPT_YIELD_INTERVAL;
if(JS_GetProperty(cx, obj,"js",&val)) /* copy branch settings from parent */
memcpy(&bg->branch,JS_GetPrivate(cx,JSVAL_TO_OBJECT(val)),sizeof(bg->branch));
bg->branch.terminated=NULL; /* could be bad pointer at any time */
bg->branch.counter=0;
bg->branch.gc_attempts=0;
if((bg->runtime = JS_NewRuntime(JAVASCRIPT_MAX_BYTES))==NULL)
return(JS_FALSE);
if((bg->cx = JS_NewContext(bg->runtime, JAVASCRIPT_CONTEXT_STACK))==NULL)
return(JS_FALSE);
if((bg->obj=js_CreateCommonObjects(bg->cx
,cfg /* common config */
,NULL /* node-specific config */
,NULL /* additional global methods */
,0 /* uptime */
,"" /* hostname */
,"" /* socklib_desc */
,&bg->branch /* js */
,NULL /* client */
,INVALID_SOCKET /* client_socket */
,NULL /* server props */
return(JS_FALSE);
bg->msg_queue = msgQueueInit(NULL,MSG_QUEUE_BIDIR);
js_CreateQueueObject(bg->cx, bg->obj, "parent_queue", bg->msg_queue);
/* Save parent's error reporter (for later use by our error reporter) */
bg->error_reporter=JS_SetErrorReporter(cx,NULL);
JS_SetErrorReporter(cx,bg->error_reporter);
JS_SetErrorReporter(bg->cx,js_ErrorReporter);
/* Set our branch callback (which calls the generic branch callback) */
JS_SetContextPrivate(bg->cx, bg);
JS_SetBranchCallback(bg->cx, js_BranchCallback);
exec_cx = bg->cx;
exec_obj = bg->obj;
} else if(JSVAL_IS_OBJECT(argv[argn])) /* Scope specified */
obj=JSVAL_TO_OBJECT(argv[argn++]);
if((filename=JS_GetStringBytes(JS_ValueToString(cx, argv[argn++])))==NULL)
return(JS_FALSE);
if(argc>argn) {
if((js_argv=JS_NewArrayObject(exec_cx, 0, NULL)) == NULL)
JS_DefineProperty(exec_cx, exec_obj, "argv", OBJECT_TO_JSVAL(js_argv)
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
JS_SetElement(exec_cx, js_argv, i-argn, &argv[i]);
JS_DefineProperty(exec_cx, exec_obj, "argc", INT_TO_JSVAL(argc-argn)
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
}
errno = 0;
if(isfullpath(filename))
strcpy(path,filename);
else {
sprintf(path,"%s%s",cfg->mods_dir,filename);
if(cfg->mods_dir[0]==0 || !fexistcase(path))
sprintf(path,"%s%s",cfg->exec_dir,filename);
JS_ClearPendingException(exec_cx);
if((script=JS_CompileFile(exec_cx, exec_obj, path))==NULL)
return(JS_FALSE);
if(background) {
bg->script = script;
*rval = OBJECT_TO_JSVAL(js_CreateQueueObject(cx, obj, NULL, bg->msg_queue));
success = _beginthread(background_thread,0,bg)!=-1;
} else {
success = JS_ExecuteScript(exec_cx, exec_obj, script, rval);
JS_DestroyScript(exec_cx, script);
}
return(success);
}
static JSBool
js_format(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char* p;
char* fmt;
uintN i;
JSString * str;
va_list arglist[64];
if((fmt=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)

rswindell
committed
memset(arglist,0,sizeof(arglist)); /* Initialize arglist to NULLs */
for (i = 1; i < argc && i<sizeof(arglist)/sizeof(arglist[0]); i++) {
if(JSVAL_IS_DOUBLE(argv[i]))
arglist[i-1]=(char*)(unsigned long)*JSVAL_TO_DOUBLE(argv[i]);
else if(JSVAL_IS_INT(argv[i]))
arglist[i-1]=(char *)JSVAL_TO_INT(argv[i]);
else {
if((str=JS_ValueToString(cx, argv[i]))==NULL) {
JS_ReportError(cx,"JS_ValueToString failed");
return(JS_FALSE);
}
arglist[i-1]=JS_GetStringBytes(str);
}
if((p=JS_vsmprintf(fmt,(char*)arglist))==NULL)
return(JS_FALSE);
str = JS_NewStringCopyZ(cx, p);
JS_smprintf_free(p);
if(str==NULL)
return(JS_FALSE);
static JSBool
js_yield(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
BOOL forced=TRUE;
if(argc)
JS_ValueToBoolean(cx, argv[0], &forced);
if(forced) {
YIELD();
} else {
MAYBE_YIELD();
}
return(JS_TRUE);
}
static JSBool
js_mswait(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JS_ValueToInt32(cx,argv[0],&val);
mswait(val);
return(JS_TRUE);
}
static JSBool
js_random(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
int32 val=100;
if(argc)
JS_ValueToInt32(cx,argv[0],&val);
JS_NewNumberValue(cx,sbbs_random(val),rval);
return(JS_TRUE);
}
static JSBool
js_time(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JS_NewNumberValue(cx,time(NULL),rval);
return(JS_TRUE);
}
static JSBool
js_beep(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
int32 freq=500;
int32 dur=500;
JS_ValueToInt32(cx,argv[0],&freq);
JS_ValueToInt32(cx,argv[1],&dur);
sbbs_beep(freq,dur);
return(JS_TRUE);
}
static JSBool
js_exit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
if(argc)
JS_DefineProperty(cx, obj, "exit_code", argv[0]
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
static JSBool
js_crc16(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char* str;
if(JSVAL_IS_VOID(argv[0]))
return(JS_TRUE);
if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
return(JS_FALSE);
*rval = INT_TO_JSVAL(crc16(str,0));
return(JS_TRUE);
}
static JSBool
js_crc32(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char* str;
if(JSVAL_IS_VOID(argv[0]))
return(JS_TRUE);
if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
return(JS_FALSE);
JS_NewNumberValue(cx,crc32(str,strlen(str)),rval);
return(JS_TRUE);
}
static JSBool
js_chksum(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
ulong sum=0;
char* p;
if(JSVAL_IS_VOID(argv[0]))
return(JS_TRUE);
if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
return(JS_FALSE);
while(*p) sum+=*(p++);
return(JS_TRUE);
}
static JSBool
js_ascii(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char* p;
char str[2];
int32 i=0;
JSString* js_str;
if(JSVAL_IS_VOID(argv[0]))
return(JS_TRUE);
if(JSVAL_IS_STRING(argv[0])) { /* string to ascii-int */
if((p=JS_GetStringBytes(JSVAL_TO_STRING(argv[0])))==NULL)
return(JS_FALSE);
return(JS_TRUE);
}
/* ascii-int to str */
JS_ValueToInt32(cx,argv[0],&i);
str[0]=(uchar)i;
str[1]=0;
if((js_str = JS_NewStringCopyZ(cx, str))==NULL)
return(JS_FALSE);
*rval = STRING_TO_JSVAL(js_str);
return(JS_TRUE);
}
static JSBool
js_ctrl(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char ch;
char* p;
char str[2];
int32 i=0;
JSString* js_str;
if(JSVAL_IS_VOID(argv[0]))
return(JS_TRUE);
if(JSVAL_IS_STRING(argv[0])) {
if((p=JS_GetStringBytes(JSVAL_TO_STRING(argv[0])))==NULL)
return(JS_FALSE);
ch=*p;
} else {
JS_ValueToInt32(cx,argv[0],&i);
ch=(char)i;
}
str[0]=toupper(ch)&~0x20;
str[1]=0;
if((js_str = JS_NewStringCopyZ(cx, str))==NULL)
return(JS_FALSE);
*rval = STRING_TO_JSVAL(js_str);
return(JS_TRUE);
}
static JSBool
js_ascii_str(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char* p;
char* str;
JSString* js_str;
if(JSVAL_IS_VOID(argv[0]))
return(JS_TRUE);
if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
return(JS_FALSE);
return(JS_FALSE);
ascii_str(p);
js_str = JS_NewStringCopyZ(cx, p);
free(p);
if(js_str==NULL)
return(JS_FALSE);
*rval = STRING_TO_JSVAL(js_str);
return(JS_TRUE);
}
static JSBool
js_strip_ctrl(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char* p;
char* str;
JSString* js_str;
if(JSVAL_IS_VOID(argv[0]))
return(JS_TRUE);
if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
return(JS_FALSE);
return(JS_FALSE);
strip_ctrl(p);
js_str = JS_NewStringCopyZ(cx, p);
free(p);
if(js_str==NULL)
return(JS_FALSE);
*rval = STRING_TO_JSVAL(js_str);
return(JS_TRUE);
}
static JSBool
js_strip_exascii(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char* p;
char* str;
JSString* js_str;
if(JSVAL_IS_VOID(argv[0]))
return(JS_TRUE);
if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
return(JS_FALSE);
return(JS_FALSE);
strip_exascii(p);
js_str = JS_NewStringCopyZ(cx, p);
free(p);
if(js_str==NULL)
return(JS_FALSE);
*rval = STRING_TO_JSVAL(js_str);
return(JS_TRUE);
}
static JSBool
js_lfexpand(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
ulong i,j;
char* inbuf;
char* outbuf;
JSString* js_str;
if(JSVAL_IS_VOID(argv[0]))
return(JS_TRUE);
if((inbuf=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
return(JS_FALSE);
if((outbuf=(char*)malloc((strlen(inbuf)*2)+1))==NULL)
return(JS_FALSE);
for(i=j=0;inbuf[i];i++) {
if(inbuf[i]=='\n' && (!i || inbuf[i-1]!='\r'))
outbuf[j++]='\r';
outbuf[j++]=inbuf[i];
}
outbuf[j]=0;
js_str = JS_NewStringCopyZ(cx, outbuf);
free(outbuf);
if(js_str==NULL)
return(JS_FALSE);
*rval = STRING_TO_JSVAL(js_str);
return(JS_TRUE);
}
static JSBool
js_word_wrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
int32 l,len=79;
ulong i,k;
int col=1;
uchar* inbuf;
char* outbuf;
char* linebuf;
JSString* js_str;
if(JSVAL_IS_VOID(argv[0]))
return(JS_TRUE);
if((inbuf=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
return(JS_FALSE);

rswindell
committed
if((outbuf=(char*)malloc((strlen(inbuf)*3)+1))==NULL)
return(JS_FALSE);
if(argc>1)
JS_ValueToInt32(cx,argv[1],&len);
if((linebuf=(char*)malloc((len*2)+2))==NULL) /* room for ^A codes */
return(JS_FALSE);
outbuf[0]=0;
for(i=l=0;inbuf[i];) {
if(inbuf[i]=='\r' || inbuf[i]==FF) {
strncat(outbuf,linebuf,l);
l=0;
else if(inbuf[i]=='\t') {
if((col%8)==0)
col++;
col+=(col%8);
} else if(inbuf[i]==CTRL_A && inbuf[i+1]!=0) {
if(l<(len*2)) {
strncpy(linebuf+l,inbuf+i,2);
l+=2;
}
i+=2;
continue;
col++;
linebuf[l]=inbuf[i++];
if(col<=len) {
l++;
continue;
}
while(k && linebuf[k]>' ' && linebuf[k-1]!=CTRL_A) k--;
if(k==0) /* continuous printing chars, no word wrap possible */
strncat(outbuf,linebuf,l+1);
else {
i-=(l-k); /* rewind to start of next word */
linebuf[k]=0;
truncsp(linebuf);
strcat(outbuf,linebuf);
}
strcat(outbuf,"\r\n");
/* skip white space (but no more than one LF) for starting of new line */
while(inbuf[i] && inbuf[i]<=' ' && inbuf[i]!='\n' && inbuf[i]!=CTRL_A) i++;
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
if(inbuf[i]=='\n') i++;
l=0;
col=1;
}
if(l) /* remainder */
strncat(outbuf,linebuf,l);
js_str = JS_NewStringCopyZ(cx, outbuf);
free(outbuf);
if(js_str==NULL)
return(JS_FALSE);
*rval = STRING_TO_JSVAL(js_str);
return(JS_TRUE);
}
static JSBool
js_quote_msg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
int32 len=79;
int i,l;
uchar* inbuf;
char* outbuf;
char* linebuf;
char* prefix=" > ";
JSString* js_str;
if(JSVAL_IS_VOID(argv[0]))
return(JS_TRUE);
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
if((inbuf=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
return(JS_FALSE);
if(argc>1)
JS_ValueToInt32(cx,argv[1],&len);
if(argc>2)
prefix=JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
if((outbuf=(char*)malloc((strlen(inbuf)*strlen(prefix))+1))==NULL)
return(JS_FALSE);
if((linebuf=(char*)malloc(len+1))==NULL)
return(JS_FALSE);
outbuf[0]=0;
for(i=l=0;inbuf[i];i++) {
if(l==0)
strcat(outbuf,prefix);
if(l<len)
linebuf[l++]=inbuf[i];
if(inbuf[i]=='\n') {
strncat(outbuf,linebuf,l);
l=0;
}
}
if(l) /* remainder */
strncat(outbuf,linebuf,l);
js_str = JS_NewStringCopyZ(cx, outbuf);
free(outbuf);
if(js_str==NULL)
return(JS_FALSE);
*rval = STRING_TO_JSVAL(js_str);
return(JS_TRUE);
}
static JSBool
js_netaddr_type(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char* str;
if(JSVAL_IS_VOID(argv[0]))
return(JS_TRUE);
if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
return(JS_FALSE);
*rval = INT_TO_JSVAL(smb_netaddr_type(str));
return(JS_TRUE);
}
static JSBool
js_rot13(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char* p;
char* str;
JSString* js_str;
if(JSVAL_IS_VOID(argv[0]))
return(JS_TRUE);
if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
return(JS_FALSE);
return(JS_FALSE);
js_str = JS_NewStringCopyZ(cx, rot13(p));
free(p);
if(js_str==NULL)
return(JS_FALSE);
*rval = STRING_TO_JSVAL(js_str);
return(JS_TRUE);
}
/* This table is used to convert between IBM ex-ASCII and HTML character entities */
/* Much of this table supplied by Deuce (thanks!) */
static struct {
int value;
char* name;
} exasctbl[128] = {
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
/* HTML val,name ASCII description */
{ 199 ,"Ccedil" }, /* 128 C, cedilla */
{ 252 ,"uuml" }, /* 129 u, umlaut */
{ 233 ,"eacute" }, /* 130 e, acute accent */
{ 226 ,"acirc" }, /* 131 a, circumflex accent */
{ 228 ,"auml" }, /* 132 a, umlaut */
{ 224 ,"agrave" }, /* 133 a, grave accent */
{ 229 ,"aring" }, /* 134 a, ring */
{ 231 ,"ccedil" }, /* 135 c, cedilla */
{ 234 ,"ecirc" }, /* 136 e, circumflex accent */
{ 235 ,"euml" }, /* 137 e, umlaut */
{ 232 ,"egrave" }, /* 138 e, grave accent */
{ 239 ,"iuml" }, /* 139 i, umlaut */
{ 238 ,"icirc" }, /* 140 i, circumflex accent */
{ 236 ,"igrave" }, /* 141 i, grave accent */
{ 196 ,"Auml" }, /* 142 A, umlaut */
{ 197 ,"Aring" }, /* 143 A, ring */
{ 201 ,"Eacute" }, /* 144 E, acute accent */
{ 230 ,"aelig" }, /* 145 ae ligature */
{ 198 ,"AElig" }, /* 146 AE ligature */
{ 244 ,"ocirc" }, /* 147 o, circumflex accent */
{ 246 ,"ouml" }, /* 148 o, umlaut */
{ 242 ,"ograve" }, /* 149 o, grave accent */
{ 251 ,"ucirc" }, /* 150 u, circumflex accent */
{ 249 ,"ugrave" }, /* 151 u, grave accent */
{ 255 ,"yuml" }, /* 152 y, umlaut */
{ 214 ,"Ouml" }, /* 153 O, umlaut */
{ 220 ,"Uuml" }, /* 154 U, umlaut */
{ 162 ,"cent" }, /* 155 Cent sign */
{ 163 ,"pound" }, /* 156 Pound sign */
{ 165 ,"yen" }, /* 157 Yen sign */
{ 8359 ,NULL }, /* 158 Pt (unicode) */
{ 402 ,NULL }, /* 402 Florin (non-standard alsi 159?) */
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
{ 225 ,"aacute" }, /* 160 a, acute accent */
{ 237 ,"iacute" }, /* 161 i, acute accent */
{ 243 ,"oacute" }, /* 162 o, acute accent */
{ 250 ,"uacute" }, /* 163 u, acute accent */
{ 241 ,"ntilde" }, /* 164 n, tilde */
{ 209 ,"Ntilde" }, /* 165 N, tilde */
{ 170 ,"ordf" }, /* 166 Feminine ordinal */
{ 186 ,"ordm" }, /* 167 Masculine ordinal */
{ 191 ,"iquest" }, /* 168 Inverted question mark */
{ 8976 ,NULL }, /* 169 Inverse "Not sign" (unicode) */
{ 172 ,"not" }, /* 170 Not sign */
{ 189 ,"frac12" }, /* 171 Fraction one-half */
{ 188 ,"frac14" }, /* 172 Fraction one-fourth */
{ 161 ,"iexcl" }, /* 173 Inverted exclamation point */
{ 171 ,"laquo" }, /* 174 Left angle quote */
{ 187 ,"raquo" }, /* 175 Right angle quote */
{ 9617 ,NULL }, /* 176 drawing symbol (unicode) */
{ 9618 ,NULL }, /* 177 drawing symbol (unicode) */
{ 9619 ,NULL }, /* 178 drawing symbol (unicode) */
{ 9474 ,NULL }, /* 179 drawing symbol (unicode) */
{ 9508 ,NULL }, /* 180 drawing symbol (unicode) */
{ 9569 ,NULL }, /* 181 drawing symbol (unicode) */
{ 9570 ,NULL }, /* 182 drawing symbol (unicode) */
{ 9558 ,NULL }, /* 183 drawing symbol (unicode) */
{ 9557 ,NULL }, /* 184 drawing symbol (unicode) */
{ 9571 ,NULL }, /* 185 drawing symbol (unicode) */
{ 9553 ,NULL }, /* 186 drawing symbol (unicode) */
{ 9559 ,NULL }, /* 187 drawing symbol (unicode) */
{ 9565 ,NULL }, /* 188 drawing symbol (unicode) */
{ 9564 ,NULL }, /* 189 drawing symbol (unicode) */
{ 9563 ,NULL }, /* 190 drawing symbol (unicode) */
{ 9488 ,NULL }, /* 191 drawing symbol (unicode) */
{ 9492 ,NULL }, /* 192 drawing symbol (unicode) */
{ 9524 ,NULL }, /* 193 drawing symbol (unicode) */
{ 9516 ,NULL }, /* 194 drawing symbol (unicode) */
{ 9500 ,NULL }, /* 195 drawing symbol (unicode) */
{ 9472 ,NULL }, /* 196 drawing symbol (unicode) */
{ 9532 ,NULL }, /* 197 drawing symbol (unicode) */
{ 9566 ,NULL }, /* 198 drawing symbol (unicode) */
{ 9567 ,NULL }, /* 199 drawing symbol (unicode) */
{ 9562 ,NULL }, /* 200 drawing symbol (unicode) */
{ 9556 ,NULL }, /* 201 drawing symbol (unicode) */
{ 9577 ,NULL }, /* 202 drawing symbol (unicode) */
{ 9574 ,NULL }, /* 203 drawing symbol (unicode) */
{ 9568 ,NULL }, /* 204 drawing symbol (unicode) */
{ 9552 ,NULL }, /* 205 drawing symbol (unicode) */
{ 9580 ,NULL }, /* 206 drawing symbol (unicode) */
{ 9575 ,NULL }, /* 207 drawing symbol (unicode) */
{ 9576 ,NULL }, /* 208 drawing symbol (unicode) */
{ 9572 ,NULL }, /* 209 drawing symbol (unicode) */
{ 9573 ,NULL }, /* 210 drawing symbol (unicode) */
{ 9561 ,NULL }, /* 211 drawing symbol (unicode) */
{ 9560 ,NULL }, /* 212 drawing symbol (unicode) */
{ 9554 ,NULL }, /* 213 drawing symbol (unicode) */
{ 9555 ,NULL }, /* 214 drawing symbol (unicode) */
{ 9579 ,NULL }, /* 215 drawing symbol (unicode) */
{ 9578 ,NULL }, /* 216 drawing symbol (unicode) */
{ 9496 ,NULL }, /* 217 drawing symbol (unicode) */
{ 9484 ,NULL }, /* 218 drawing symbol (unicode) */
{ 9608 ,NULL }, /* 219 drawing symbol (unicode) */
{ 9604 ,NULL }, /* 220 drawing symbol (unicode) */
{ 9612 ,NULL }, /* 221 drawing symbol (unicode) */
{ 9616 ,NULL }, /* 222 drawing symbol (unicode) */
{ 9600 ,NULL }, /* 223 drawing symbol (unicode) */
{ 945 ,NULL }, /* 224 alpha symbol */
{ 223 ,"szlig" }, /* 225 sz ligature (beta symbol) */
{ 915 ,NULL }, /* 226 omega symbol */
{ 960 ,NULL }, /* 227 pi symbol*/
{ 931 ,NULL }, /* 228 epsilon symbol */
{ 963 ,NULL }, /* 229 o with stick */
{ 181 ,"micro" }, /* 230 Micro sign (Greek mu) */
{ 964 ,NULL }, /* 231 greek char? */
{ 934 ,NULL }, /* 232 greek char? */
{ 920 ,NULL }, /* 233 greek char? */
{ 937 ,NULL }, /* 234 greek char? */
{ 948 ,NULL }, /* 235 greek char? */
{ 8734 ,NULL }, /* 236 infinity symbol (unicode) */
{ 949 ,NULL }, /* 238 rounded E */
{ 8745 ,NULL }, /* 239 unside down U (unicode) */
{ 8801 ,NULL }, /* 240 drawing symbol (unicode) */
{ 177 ,"plusmn" }, /* 241 Plus or minus */
{ 8805 ,NULL }, /* 242 drawing symbol (unicode) */
{ 8804 ,NULL }, /* 243 drawing symbol (unicode) */
{ 8992 ,NULL }, /* 244 drawing symbol (unicode) */
{ 8993 ,NULL }, /* 245 drawing symbol (unicode) */
{ 247 ,"divide" }, /* 246 Division sign */
{ 8776 ,NULL }, /* 247 two squiggles (unicode) */
{ 176 ,"deg" }, /* 248 Degree sign */
{ 8729 ,NULL }, /* 249 drawing symbol (unicode) */
{ 183 ,"middot" }, /* 250 Middle dot */
{ 8730 ,NULL }, /* 251 check mark (unicode) */
{ 8319 ,NULL }, /* 252 superscript n (unicode) */
{ 178 ,"sup2" }, /* 253 superscript 2 */
{ 9632 ,NULL }, /* 254 drawing symbol (unicode) */
{ 160 ,"nbsp" } /* 255 non-breaking space */
};
static struct {
int value;
char* name;
} lowasctbl[32] = {
{ 160 ,"nbsp" }, /* NULL non-breaking space */
{ 9786 ,NULL }, /* white smiling face */
{ 9787 ,NULL }, /* black smiling face */
{ 9829 ,"hearts" }, /* black heart suit */
{ 9830 ,"diams" }, /* black diamond suit */
{ 9827 ,"clubs" }, /* black club suit */
{ 9824 ,"spades" }, /* black spade suit */
{ 8226 ,"bull" }, /* bullet */
{ 9688 ,NULL }, /* inverse bullet */
{ 9702 ,NULL }, /* white bullet */
{ 9689 ,NULL }, /* inverse white circle */
{ 9794 ,NULL }, /* male sign */
{ 9792 ,NULL }, /* female sign */
{ 9834 ,NULL }, /* eighth note */
{ 9835 ,NULL }, /* beamed eighth notes */
{ 9788 ,NULL }, /* white sun with rays */
{ 9654 ,NULL }, /* black right-pointing triangle */
{ 9664 ,NULL }, /* black left-pointing triangle */
{ 8597 ,NULL }, /* up down arrow */
{ 8252 ,NULL }, /* double exclamation mark */
{ 182 ,"para" }, /* pilcrow sign */
{ 167 ,"sect" }, /* section sign */
{ 9644 ,NULL }, /* black rectangle */
{ 8616 ,NULL }, /* up down arrow with base */
{ 8593 ,"uarr" }, /* upwards arrow */
{ 8595 ,"darr" }, /* downwards arrow */
{ 8594 ,"rarr" }, /* rightwards arrow */
{ 8592 ,"larr" }, /* leftwards arrow */
{ 8985 ,NULL }, /* turned not sign */
{ 8596 ,"harr" }, /* left right arrow */
{ 9650 ,NULL }, /* black up-pointing triangle */
{ 9660 ,NULL } /* black down-pointing triangle */
static JSBool
js_html_encode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
ulong i,j;
uchar* tmpbuf;
uchar* param;
char* lastparam;
JSBool exascii=JS_TRUE;
JSBool wsp=JS_TRUE;
JSBool ansi=JS_TRUE;
JSBool ctrl_a=JS_TRUE;
JSString* js_str;
int fg=7;
int bg=0;
BOOL blink=FALSE;
BOOL bold=FALSE;
int esccount=0;
char ansi_seq[MAX_ANSI_SEQ+1];
int ansi_param[MAX_ANSI_PARAMS];
int k,l;
int hpos=0;
int currrow=0;