135 lines · 3.1 KB · C
RawDownload
#include "jsi.h" /* Dynamically grown string buffer */ void js_putc(js_State *J, js_Buffer **sbp, int c){	js_Buffer *sb = *sbp;	if (!sb) {		sb = js_malloc(J, sizeof *sb);		sb->n = 0;		sb->m = sizeof sb->s;		*sbp = sb;	} else if (sb->n == sb->m) {		sb = js_realloc(J, sb, (sb->m *= 2) + soffsetof(js_Buffer, s));		*sbp = sb;	}	sb->s[sb->n++] = c;} void js_puts(js_State *J, js_Buffer **sb, const char *s){	while (*s)		js_putc(J, sb, *s++);} void js_putm(js_State *J, js_Buffer **sb, const char *s, const char *e){	while (s < e)		js_putc(J, sb, *s++);} /* Use an AA-tree to quickly look up interned strings. */ struct js_StringNode{	js_StringNode *left, *right;	int level;	char string[1];}; static js_StringNode jsS_sentinel = { &jsS_sentinel, &jsS_sentinel, 0, ""}; static js_StringNode *jsS_newstringnode(js_State *J, const char *string, const char **result){	int n = strlen(string);	js_StringNode *node = js_malloc(J, soffsetof(js_StringNode, string) + n + 1);	node->left = node->right = &jsS_sentinel;	node->level = 1;	memcpy(node->string, string, n + 1);	return *result = node->string, node;} static js_StringNode *jsS_skew(js_StringNode *node){	if (node->left->level == node->level) {		js_StringNode *temp = node;		node = node->left;		temp->left = node->right;		node->right = temp;	}	return node;} static js_StringNode *jsS_split(js_StringNode *node){	if (node->right->right->level == node->level) {		js_StringNode *temp = node;		node = node->right;		temp->right = node->left;		node->left = temp;		++node->level;	}	return node;} static js_StringNode *jsS_insert(js_State *J, js_StringNode *node, const char *string, const char **result){	if (node != &jsS_sentinel) {		int c = strcmp(string, node->string);		if (c < 0)			node->left = jsS_insert(J, node->left, string, result);		else if (c > 0)			node->right = jsS_insert(J, node->right, string, result);		else			return *result = node->string, node;		node = jsS_skew(node);		node = jsS_split(node);		return node;	}	return jsS_newstringnode(J, string, result);} static void dumpstringnode(js_StringNode *node, int level){	int i;	if (node->left != &jsS_sentinel)		dumpstringnode(node->left, level + 1);	printf("%d: ", node->level);	for (i = 0; i < level; ++i)		putchar('\t');	printf("'%s'\n", node->string);	if (node->right != &jsS_sentinel)		dumpstringnode(node->right, level + 1);} void jsS_dumpstrings(js_State *J){	js_StringNode *root = J->strings;	printf("interned strings {\n");	if (root && root != &jsS_sentinel)		dumpstringnode(root, 1);	printf("}\n");} static void jsS_freestringnode(js_State *J, js_StringNode *node){	if (node->left != &jsS_sentinel) jsS_freestringnode(J, node->left);	if (node->right != &jsS_sentinel) jsS_freestringnode(J, node->right);	js_free(J, node);} void jsS_freestrings(js_State *J){	if (J->strings && J->strings != &jsS_sentinel)		jsS_freestringnode(J, J->strings);} const char *js_intern(js_State *J, const char *s){	const char *result;	if (!J->strings)		J->strings = &jsS_sentinel;	J->strings = jsS_insert(J, J->strings, s, &result);	return result;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t