Esempio n. 1
0
/**
 * @brief Reallocate the space for a given string
 *
 * @param str the string to reallocate space for
 * @param size the new size to assume, or if 0, the size is doubled
 * @return the reallocated string
 */
lstring_t *lstr_realloc(lstring_t *str, size_t size) {
  assert(str->hash == 0);
  if (size == 0) size = str->length * 2;
  str->length = size;
  return gc_realloc(str, sizeof(lstring_t) + size);
}
atom_p read(FILE* input) {
	fscanf(input, " ");
	if (feof(input))
		return NULL;
	
	char* str = NULL;
	if ( fscanf(input, "\"%m[^\"]\"", &str) == 1 ) {
		atom_p atom = gc_alloc(sizeof(atom_t));
		atom->type = T_STR;
		atom->str = gc_alloc(strlen(str) + 1);
		strcpy(atom->str, str);
		free(str);
		return atom;
	}
	
	int c = getc(input);
	if ( isdigit(c) ) {
		double value = c - '0';
		while ( (c = getc(input)), c >= '0' && c <= '9' ) {
			value = value * 10;
			value += c - '0';
		}
		
		if (c == '.') {
			double fraction = 0.1;
			while ( (c = getc(input)), c >= '0' && c <= '9' ) {
				value += (c - '0') * fraction;
				fraction /= 10;
			}
		}
		
		ungetc(c, input);
		
		atom_p atom = gc_alloc(sizeof(atom_t));
		atom->type = T_NUM;
		atom->num = value;
		return atom;
	} else if (c == '(') {
		atom_p atom = gc_alloc(sizeof(atom_t));
		atom->type = T_ARRAY;
		atom->array.len = 0;
		atom->array.ptr = NULL;
		
		int c = 0;
		while (true) {
			fscanf(input, " ");
			if ( (c = getc(input)) == ')' )
				return atom;
			ungetc(c, input);
			
			atom_p item = read(input);
			if (item == NULL)
				return error_atom("unexpected EOF while reading array elements");
			
			atom->array.ptr = gc_realloc(atom->array.ptr, atom->array.len * sizeof(atom->array.ptr[0]), (atom->array.len + 1) * sizeof(atom->array.ptr[0]));
			atom->array.len += 1;
			atom->array.ptr[atom->array.len - 1] = item;
		}
	} else if (c == '{') {
		atom_p atom = gc_alloc_zeroed(sizeof(atom_t));
		atom->type = T_OBJ;
		
		char c = 0;
		fscanf(input, " %c", &c);
		if (c == '}')
			return atom;
		ungetc(c, input);
		
		do {
			char* key = NULL;
			if ( fscanf(input, " %m[^:{}() \f\n\r\t\v]", &key) != 1 )
				return error_atom("expected object property name after '{' or ','");
			
			fscanf(input, " %c", &c);
			if (c != ':')
				return error_atom("expected ':' after object property name");
			
			atom_p value = read(input);
			hash_set(atom, key, value);
		} while( fscanf(input, " %c", &c) == 1 && c == ',' );
		
		if (c != '}')
			return error_atom("expected '}' or ',' after object property value");
		return atom;
	} else {
		ungetc(c, input);
	}
	
	if ( fscanf(input, " %m[^:{}() \f\n\r\t\v]", &str) == 1 ) {
		atom_p atom = NULL;
		
		if ( strcmp(str, "nil") == 0 ) {
			atom = nil_atom;
			free(str);
		} else if ( strcmp(str, "true") == 0 ) {
			atom = true_atom;
			free(str);
		} else if ( strcmp(str, "false") == 0 ) {
			atom = false_atom;
			free(str);
		} else {
			atom = gc_alloc_uncollected(sizeof(atom_t));
			atom->type = T_SYM;
			atom->sym = gc_alloc(strlen(str) + 1);
			strcpy(atom->sym, str);
			free(str);
		}
		
		return atom;
	}
	
	fscanf(input, "%*[^\n]");
	return error_atom("syntax error, ignoring rest of line");
}
Esempio n. 3
0
extern "C" void* gc_compat_realloc(void* ptr, size_t sz) {
    if (ptr == NULL)
        return gc_alloc(sz, GCKind::CONSERVATIVE);
    return gc_realloc(ptr, sz);
}
Esempio n. 4
0
File: parse.c Progetto: GJDuck/SMCHR
/*
 * Read a string.
 */
static char *token_readstring(context_t cxt, char end)
{
    size_t size = 128;
    size_t len = 0;
    char *buf = (char *)gc_malloc(size+1);
    char c;

    while (*cxt->str != end)
    {
        if (!isprint(*cxt->str))
            return NULL;
        if (len >= size)
        {
            size *= 2;
            buf = (char *)gc_realloc(buf, size);
        }
        c = *cxt->str;
        buf[len++] = *cxt->str++;
        if (c == '\\')
        {
            c = *cxt->str++;
            switch (c)
            {
                case '\0':
                    return NULL;
                case '0':
                    buf[len-1] = '\0';
                    break;
                case 'n':
                    buf[len-1] = '\n';
                    break;
                case 'r':
                    buf[len-1] = '\r';
                    break;
                case 't':
                    buf[len-1] = '\r';
                    break;
                case 'a':
                    buf[len-1] = '\a';
                    break;
                case 'b':
                    buf[len-1] = '\b';
                    break;
                case 'f':
                    buf[len-1] = '\f';
                    break;
                case 'x':
                {
                    char tmp[3];
                    tmp[0] = *cxt->str++;
                    if (!isxdigit(tmp[0]))
                        return NULL;
                    tmp[1] = *cxt->str++;
                    if (!isxdigit(tmp[1]))
                        return NULL;
                    tmp[2] = '\0';
                    unsigned x;
                    if (sscanf(tmp, "%x", &x) != 1)
                        return NULL;
                    buf[len-1] = (char)x;
                    break;
                }
                default:
                    if (c == '\n')
                        cxt->line++;
                    buf[len-1] = c;
                    break;
            }
        }
    }

    buf[len] = '\0';
    buf = gc_realloc(buf, len+1);
    cxt->str++;
    return buf;
}
Esempio n. 5
0
/*
 * Read a line from the prompt.
 */
extern char *prompt(bool silent, FILE *input, history_t *state)
{
    const char *prompt = (silent? "": "> ");

    while (true)
    {
#ifndef WINDOWS
        if (use_readline && input == stdin)
        {
            // Set the state:
            if (use_state)
            {
                if (*state != NULL)
                {
                    history_set_history_state((HISTORY_STATE *)*state);
                    free(*state);
                    *state = NULL;
                }
                else
                    history_set_history_state(empty_state);
            }

            // Readline:
            char *line = readline(prompt);

            if (line != NULL)
            {
                bool all_space = true;
                for (size_t i = 0; line[i]; i++)
                {
                    if (!isspace(line[i]))
                    {
                        all_space = false;
                        break;
                    }
                }
                if (!all_space)
                    add_history(line);
            }

            if (use_state)
                *state = (history_t)history_get_history_state();

            return line;
        }
#endif      /* WINDOWS */

        // Non-readline:
        size_t size = 128, len = 0;
        char *line = gc_malloc(size*sizeof(char));
        char c;
        fputs(prompt, stdout);
        while (!feof(input) && !ferror(input) && (c = getc(input)) != '\n')
        {
            if (len >= size-1)
            {
                size = (3 * size) / 2;
                line = (char *)gc_realloc(line, size*sizeof(char));
            }
            line[len++] = c;
        }
        if (feof(input) || ferror(input))
            return NULL;
        line[len] = '\0';
        return line;
    }
}