# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
-CFLAGS = -ggdb -fsigned-char -fno-builtin -Wall -Wextra -Werror -pedantic
+CFLAGS = -ggdb -Wall -Wextra -pedantic #-Werror
CFILES = $(wildcard *.c)
all:
@echo $(CFILES)
- @gcc -m32 $(CFLAGS) $(CFILES) -o shell
+ @g++ $(CFLAGS) $(CFILES) -o shell
arm:
- @arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 $(CFLAGS) -c *.c
- @arm-none-eabi-ar r libinterp.a *.o
+ @g++ $(CFLAGS) -c *.c
+ @ar r libinterp.a *.o
@rm *.o
#include "builtins.h"
+#include <memory.h>
#include <stdlib.h>
#include <string.h>
-#define IF_SIG (uint32_t)-1
-#define WHILE_SIG (uint32_t)-2
-#define ELSE_SIG (uint32_t)-3
-#define FUNC_SIG (uint32_t)-4
+#define IF_SIG (size_t)-1
+#define WHILE_SIG (size_t)-2
+#define ELSE_SIG (size_t)-3
+#define FUNC_SIG (size_t)-4
variable bopen = {
- 0, CFUNC, 0, 0, {.p = (uint32_t)bracket_open}
+ 0, CFUNC, 0, 0, {.p = (size_t)bracket_open}
};
variable bclose = {
- 0, CFUNC, 0, 0, {.p = (uint32_t)bracket_close}
+ 0, CFUNC, 0, 0, {.p = (size_t)bracket_close}
};
int bn_if(instance *it);
int bn_if(instance *it)
{
variable *cond = (variable *)ipop(it);
- uint32_t result = cond->value.p;
+ size_t result = cond->value.p;
ipush(it, result);
ipush(it, IF_SIG);
return 0;
}
-static uint32_t if_cond = 0;
+static size_t if_cond = 0;
int bn_else(instance *it)
{
- uint32_t cond = if_cond;
+ size_t cond = if_cond;
if (cond != 0)
it->sindent = SKIP | it->indent;
ipush(it, ELSE_SIG);
*/
int bn_end(instance *it)
{
- uint32_t sig = ipop(it);
+ size_t sig = ipop(it);
if (sig == IF_SIG) {
if_cond = ipop(it);
} else if (sig == WHILE_SIG) {
- uint32_t lnidx = ipop(it);
- if (lnidx != (uint32_t)-1)
+ size_t lnidx = ipop(it);
+ if (lnidx != (size_t)-1)
it->lnidx = lnidx - 1;
} else if (sig == CALL_SIG) {
it->lnidx = ipop(it);
int bn_while(instance *it)
{
variable *cond = (variable *)ipop(it);
- uint32_t result = cond->value.p;
+ size_t result = cond->value.p;
if (result == 0) {
it->sindent = SKIP | it->indent;
- ipush(it, (uint32_t)-1);
+ ipush(it, (size_t)-1);
} else {
ipush(it, it->lnidx);
}
variable *s = igetarg(it, 0);
variable **ops = iparse(it, (const char *)s->value.p);
if (ops == 0) {
- ipush(it, (uint32_t)make_varf(0, 0.0f));
+ ipush(it, (size_t)make_varf(0, 0.0f));
// return zero, don't let bad solves break the script
return 0;
}
variable *a = isolve(it, ops, 0);
free(ops);
- ipush(it, (uint32_t)a);
+ ipush(it, (size_t)a);
return 0;
}
{
variable *a = igetarg(it, 0);
int size = igetarg(it, 1)->value.f;
- uint32_t i0 = a->value.p;
- variable *array = calloc(size, sizeof(variable));
+ size_t i0 = a->value.p;
+ variable *array = (variable *)calloc(size, sizeof(variable));
array[0].type = a->type;
array[0].value.p = i0;
a->array = size;
- a->value.p = (uint32_t)array;
+ a->value.p = (size_t)array;
return 0;
}
f = strlen((char *)a->value.p);
else
f = a->array;
- ipush(it, (uint32_t)make_varf(0, f));
+ ipush(it, (size_t)make_varf(0, f));
return 0;
}
if (b->type == NUMBER) {
int len = strlen((char *)a->value.p);
- char *newstr = malloc(len + 2);
+ char *newstr = (char *)malloc(len + 2);
memcpy(newstr, (char *)a->value.p, len);
newstr[len] = b->value.f;
newstr[len + 1] = '\0';
free((void *)a->value.p);
- a->value.p = (uint32_t)newstr;
+ a->value.p = (size_t)newstr;
} else if (b->type == STRING) {
int len1 = strlen((char *)a->value.p);
int len2 = strlen((char *)b->value.p);
- char *newstr = malloc(len1 + len2);
+ char *newstr = (char *)malloc(len1 + len2);
memcpy(newstr, (char *)a->value.p, len1);
memcpy(newstr + len1, (char *)b->value.p, len2);
newstr[len1 + len2] = '\0';
free((void *)a->value.p);
- a->value.p = (uint32_t)newstr;
+ a->value.p = (size_t)newstr;
}
- ipush(it, (uint32_t)a);
+ ipush(it, (size_t)a);
return 0;
}
#include "parser.h"
-#define SKIP_SIG (uint32_t)-5
-#define CALL_SIG (uint32_t)-6
+#define SKIP_SIG (size_t)-5
+#define CALL_SIG (size_t)-6
// open bracket 'operator', for use in a compiled line
extern variable bopen;
#include <stdlib.h>
#define OP_DEF(o) int op_##o(variable **r, variable *a, variable *b)
-#define OP_VAR(o) {0, OPERATOR, 0, 0, {.p = (uint32_t)op_##o}}
+#define OP_VAR(o) {0, OPERATOR, 0, 0, {.p = (size_t)op_##o}}
#define OP_NONE {0, OPERATOR, 0, 0, {.p = 0x0BADCAFE}}
OP_DEF(idx);
variable *igetop(const char *name, int *retlen)
{
- for (uint32_t i = 0; i < OPS_COUNT; i++) {
+ for (size_t i = 0; i < OPS_COUNT; i++) {
if (opnames[i] == 0)
continue;
int len = strlen(opnames[i]);
int idx = b->value.f;
if (idx >= a->array) {
- variable *newarray = calloc(idx + 1, sizeof(variable));
+ variable *newarray = (variable *)calloc(idx + 1, sizeof(variable));
void *old = (void *)a->value.p;
- a->value.p = (uint32_t)memcpy(newarray, (variable *)a->value.p,
+ a->value.p = (size_t)memcpy(newarray, (variable *)a->value.p,
a->array * sizeof(variable));
free(old);
a->array = idx + 1;
} else if (b->type == STRING) {
a->type = STRING;
free((void *)a->value.p);
- a->value.p = (uint32_t)strclone((char *)b->value.p);
+ a->value.p = (size_t)strclone((char *)b->value.p);
(*r)->type = STRING;
- (*r)->value.p = (uint32_t)strclone((char *)a->value.p);
+ (*r)->value.p = (size_t)strclone((char *)a->value.p);
} else {
return seterror(EBADPARAM);
}
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
/**
* Limitations for an instance. TODO make dynamic (no limits).
instance *it = (instance *)malloc(sizeof(instance));
it->vars = (variable *)calloc(MAX_VARS, sizeof(variable));
it->names = (char **)calloc(MAX_VARS, sizeof(char *));
- it->stack = (uint32_t *)malloc(MAX_STACK * sizeof(uint32_t));
+ it->stack = (size_t *)malloc(MAX_STACK * sizeof(size_t));
it->stidx = 0;
it->lines = (variable ***)calloc(MAX_LINES, sizeof(variable **));
it->lnidx = 0;
{
itryfree(it->ret);
- for (uint32_t i = 0; i < MAX_LINES; i++) {
+ for (size_t i = 0; i < MAX_LINES; i++) {
if (it->lines[i] == 0)
continue;
}
free(it->lines);
- for (uint32_t i = 0; i < MAX_VARS; i++) {
+ for (size_t i = 0; i < MAX_VARS; i++) {
if (it->vars[i].type == STRING || it->vars[i].array > 0)
free((void *)it->vars[i].value.p);
free(it->names[i]);
for (int j = 0; j < 32; j++) {
variable *v = ops[j];
if (v != 0) {
- if (((uint32_t)v & OP_MAGIC) == OP_MAGIC)
+ if (((size_t)v & OP_MAGIC) == OP_MAGIC)
continue;
if (v->type == FUNC || v->type == CFUNC)
// stack operations
//
-void ipush(instance *it, uint32_t v)
+void ipush(instance *it, size_t v)
{
it->stack[it->stidx++] = v;
}
-uint32_t ipop(instance *it)
+size_t ipop(instance *it)
{
return it->stack[--it->stidx];
}
-void ipopm(instance *it, uint32_t count)
+void ipopm(instance *it, size_t count)
{
it->stidx -= count;
}
-variable *igetarg(instance *it, uint32_t n)
+variable *igetarg(instance *it, size_t n)
{
return (variable *)it->stack[it->stidx - n - 1];
}
variable *igetvar(instance *it, const char *name)
{
if (isalpha(name[0])) {
- for (uint32_t i = 0; i < MAX_VARS; i++) {
+ for (size_t i = 0; i < MAX_VARS; i++) {
if (it->names[i] == 0) {
it->names[i] = strclone(name);
// default to 0 float
{
variable *v = igetvar(it, name);
v->type = CFUNC;
- v->value.p = (uint32_t)func;
+ v->value.p = (size_t)func;
}
void inew_number(instance *it, const char *name, float f)
{
variable *v = igetvar(it, name);
v->type = STRING;
- v->value.p = (uint32_t)strclone(s);
+ v->value.p = (size_t)strclone(s);
}
int iaddline(instance *it, const char *s)
for (int i = 0; i < 32; i++) {
variable *v = it->lines[it->lnidx][i];
if (v != 0) {
- if (((uint32_t)v & OP_MAGIC) == OP_MAGIC) {
+ if (((size_t)v & OP_MAGIC) == OP_MAGIC) {
copy[i] = v;
continue;
}
free((void *)ret->value.p);
ret->type = it->ret->type;
if (ret->type == STRING)
- ret->value.p = (uint32_t)strclone((char *)it->ret->value.p);
+ ret->value.p = (size_t)strclone((char *)it->ret->value.p);
else
ret->value.p = it->ret->value.p;
itryfree(it->ret);
return 0;
}
-variable *isolve_(instance *it, variable **ops, uint32_t count);
-variable *isolve(instance *it, variable **ops, uint32_t count)
+variable *isolve_(instance *it, variable **ops, size_t count);
+variable *isolve(instance *it, variable **ops, size_t count)
{
if (count == 0)
for (count = 0; ops[count] != 0; count++);
- for (uint32_t i = 0; i < count; i++) {
- if (((uint32_t)ops[i] & OP_MAGIC) == OP_MAGIC) {
- uint32_t count_ = (uint32_t)ops[i] & 0xFF;
+ for (size_t i = 0; i < count; i++) {
+ if (((size_t)ops[i] & OP_MAGIC) == OP_MAGIC) {
+ size_t count_ = (size_t)ops[i] & 0xFF;
ops[i] = isolve(it, ops + i + 1, count_);
- for (uint32_t j = 1; j <= count_; j++)
+ for (size_t j = 1; j <= count_; j++)
ops[i + j] = 0;
}
}
return isolve_(it, ops, count);
}
-variable *isolve_(instance *it, variable **ops, uint32_t count)
+variable *isolve_(instance *it, variable **ops, size_t count)
{
// first, look for functions
- for (uint32_t i = 0; i < count; i++) {
+ for (size_t i = 0; i < count; i++) {
if (ops[i] == 0)
continue;
if (ops[i]->type == CFUNC || ops[i]->type == FUNC) {
- uint32_t nargs = (uint32_t)ops[i + 1] - 1;
- uint32_t start = i;
+ size_t nargs = (size_t)ops[i + 1] - 1;
+ size_t start = i;
i++;
if (nargs > 0)
i++;
for (j = nargs; j > 0 && i < count; i++) {
if (ops[i] != 0) {
if (ops[start]->type == CFUNC) {
- it->stack[it->stidx + j - 1] = (uint32_t)ops[i];
+ it->stack[it->stidx + j - 1] = (size_t)ops[i];
} else {
char namebuf[6];
snprintf(namebuf, 6, "arg%u",
func_t func = (func_t)ops[start]->value.p;
it->stidx += nargs;
- uint32_t sidx = it->stidx;
+ size_t sidx = it->stidx;
int ret = 0;
if (!(it->sindent & SKIP) || (func == bracket_open ||
func == bracket_close))
}
ops[start + 1] = 0;
- for (uint32_t j = start + 2; j < i; j++) {
+ for (size_t j = start + 2; j < i; j++) {
itryfree(ops[j]);
ops[j] = 0;
}
}
// next, operators
- for (uint32_t j = 0; j < OPS_COUNT; j += 2) {
- for (uint32_t i = 0; i < count; i++) {
+ for (size_t j = 0; j < OPS_COUNT; j += 2) {
+ for (size_t i = 0; i < count; i++) {
if (ops[i] == 0)
continue;
if (ops[i]->type == OPERATOR) {
- if (ops[i]->value.p != (uint32_t)opvars[j].value.p) {
- if (ops[i]->value.p != (uint32_t)opvars[j + 1].value.p)
+ if (ops[i]->value.p != (size_t)opvars[j].value.p) {
+ if (ops[i]->value.p != (size_t)opvars[j + 1].value.p)
continue;
}
opfunc_t func = (opfunc_t)ops[i]->value.p;
- uint32_t aidx = i - 1;
+ size_t aidx = i - 1;
while (ops[aidx] == 0 && aidx != 0)
aidx--;
if (ops[aidx] == 0)
return 0;
- uint32_t bidx = i + 1;
+ size_t bidx = i + 1;
while (ops[bidx] == 0 && ++bidx < count);
if (bidx >= count)
return 0;
// implicit multiply
/*if (ops[0] != 0 && ops[0]->type == NUMBER) {
- for (uint32_t i = 1; i < count; i++) {
+ for (size_t i = 1; i < count; i++) {
if (ops[i] != 0 && ops[i]->type == NUMBER)
ops[0]->value.f *= ops[i]->value.f;
}
variable **iparse(instance *it, const char *s)
{
variable **ops = 0;
- uint32_t ooffset = 0;
+ size_t ooffset = 0;
int32_t boffset = 1;
size_t offset = 0;
uint8_t prevNum = 0;
while (isblank(s[end]))
end++;
if (s[end] == '(') {
- uint32_t argidx = ooffset;
- uint32_t argcount = 1;
+ size_t argidx = ooffset;
+ size_t argcount = 1;
ooffset++;
end++;
- uint32_t last = end;
+ size_t last = end;
for (int c = 0; c >= 0; end++) {
if (s[end] == '(')
c++;
if (c == 0 && last != end && (s[end] == ',' || s[end] == ')' || s[end] == '\0')) {
argcount++;
char *arg = strnclone(s + last, end - last);
- uint32_t parenidx = ooffset;
+ size_t parenidx = ooffset;
ooffset++;
variable **moreops = iparse(it, arg);
- uint32_t count = 0;
+ size_t count = 0;
if (moreops != 0) {
- for (uint32_t i = 0; moreops[i] != 0; count++, i++)
+ for (size_t i = 0; moreops[i] != 0; count++, i++)
ops[ooffset++] = moreops[i];
free(moreops);
}
}
i++;
char *word = strnclone(s + offset + 1, i - offset - 2);
- uint32_t parenidx = ooffset;
+ size_t parenidx = ooffset;
ooffset++;
variable **moreops = iparse(it, word);
- uint32_t count = 0;
+ size_t count = 0;
if (moreops != 0) {
- for (uint32_t i = 0; moreops[i] != 0; count++, i++)
+ for (size_t i = 0; moreops[i] != 0; count++, i++)
ops[ooffset++] = moreops[i];
free(moreops);
}
offset = i;
prevNum += 2;
} else if (s[offset] == '[') {
- /*uint32_t i = offset + 1;
- uint32_t j = i;
+ /*size_t i = offset + 1;
+ size_t j = i;
while (s[offset] != ']') {
if (s[offset] == ';') {
typedef struct {
variable *vars; /**< An array of defined variables */
char **names; /**< An array of names for the variables */
- uint32_t *stack; /**< The instance's stack */
- uint32_t stidx; /**< The instance's position in the stack */
+ size_t *stack; /**< The instance's stack */
+ size_t stidx; /**< The instance's position in the stack */
variable ***lines; /**< Compiled data for each line of script */
- uint32_t lnidx; /**< Position in script/line being run */
+ size_t lnidx; /**< Position in script/line being run */
variable *ret; /**< Pointer to the last returned variable */
uint8_t indent; /**< Current indent/scope of the instance */
uint8_t sindent; /**< Indent of scope to skip, for false conditionals */
* @param it the current instance
* @return the popped value
*/
-uint32_t ipop(instance *it);
+size_t ipop(instance *it);
/**
* Pushes a word to the instance's stack.
* @param it the current instance
* @param v the word to push
*/
-void ipush(instance *it, uint32_t v);
+void ipush(instance *it, size_t v);
/**
* Gets the nth argument passed to the current C function.
* @param n the index of the argument, zero-based
* @return the argument's variable
*/
-variable *igetarg(instance *it, uint32_t n);
+variable *igetarg(instance *it, size_t n);
/**
* Parses the given line, returning compiled data to run.
* @param count the size of the ops array, zero if unknown
* @return the variable returned by the line, null if none
*/
-variable *isolve(instance *it, variable **ops, uint32_t count);
+variable *isolve(instance *it, variable **ops, size_t count);
#endif // PARSER_H_
--- /dev/null
+/**
+ * @file shell.c
+ * File loader to test scripts in host environment
+ *
+ * Copyright (C) 2018 Clyne Sullivan
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "parser.h"
+
+int print(instance *it)
+{
+ variable *s = igetarg(it, 0);
+ if (s->type == NUMBER) {
+ if (s->value.f == (int)s->value.f)
+ printf("%d\n", (int)s->value.f);
+ else
+ printf("%.3f\n", s->value.f);
+ } else if (s->value.p != 0) {
+ printf("%s\n", (char *)s->value.p);
+ }
+ return 0;
+}
+
+int gets(instance *it)
+{
+ char *line = 0;
+ size_t size;
+ getline(&line, &size, stdin);
+ *strchr(line, '\n') = '\0';
+ variable *v = make_vars(0, line);
+ free(line);
+ ipush(it, (size_t)v);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ if (argc != 2) {
+ printf("Usage: %s file\n", argv[0]);
+ return -1;
+ }
+
+ FILE *fp = fopen(argv[1], "r");
+ if (fp == 0) {
+ printf("Could not open file: %s\n", argv[1]);
+ return -1;
+ }
+
+ instance *it = inewinstance();
+ inew_cfunc(it, "print", print);
+ inew_cfunc(it, "gets", gets);
+
+ char *line = 0;
+ size_t size;
+ int result;
+ while (getline(&line, &size, fp) != -1) {
+ *strchr(line, '\n') = '\0';
+ result = iaddline(it, line);
+ if (result != 0)
+ printf("Error: %d\n", result);
+ }
+ free(line);
+ fclose(fp);
+
+ irun(it);
+ idelinstance(it);
+ return 0;
+}
+
+++ /dev/null
-/**
- * @file shell.c
- * File loader to test scripts in host environment
- *
- * Copyright (C) 2018 Clyne Sullivan
- *
- * 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "parser.h"
-
-int print(instance *it)
-{
- variable *s = igetarg(it, 0);
- if (s->type == NUMBER) {
- if (s->value.f == (int)s->value.f)
- printf("%d\n", (int)s->value.f);
- else
- printf("%.3f\n", s->value.f);
- } else if (s->value.p != 0) {
- printf("%s\n", (char *)s->value.p);
- }
- return 0;
-}
-
-int gets(instance *it)
-{
- char *line = 0;
- size_t size;
- getline(&line, &size, stdin);
- *strchr(line, '\n') = '\0';
- variable *v = make_vars(0, line);
- free(line);
- ipush(it, (uint32_t)v);
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- if (argc != 2) {
- printf("Usage: %s file\n", argv[0]);
- return -1;
- }
-
- FILE *fp = fopen(argv[1], "r");
- if (fp == 0) {
- printf("Could not open file: %s\n", argv[1]);
- return -1;
- }
-
- instance *it = inewinstance();
- inew_cfunc(it, "print", print);
- inew_cfunc(it, "gets", gets);
-
- char *line = 0;
- size_t size;
- int result;
- while (getline(&line, &size, fp) != -1) {
- *strchr(line, '\n') = '\0';
- result = iaddline(it, line);
- if (result != 0)
- printf("Error: %d\n", result);
- }
- free(line);
- fclose(fp);
-
- irun(it);
- idelinstance(it);
- return 0;
-}
-
+++ /dev/null
-/**
- * @file string.c
- * Provides string.h from stdlib, plus some extra functions.
- *
- * Copyright (C) 2018 Clyne Sullivan
- *
- * 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-#include "string.h"
-
-#include <stdlib.h>
-
-char *strnclone(const char *s, size_t c)
-{
- char *b = strncpy((char *)malloc(c + 1), s, c);
- b[c] = '\0';
- return b;
-}
-
-char *strclone(const char *s)
-{
- return strnclone(s, strlen(s));
-}
-
-char *fixstring(const char *s)
-{
- char *n = malloc(strlen(s) + 1 - 2);
- int j = 0;
- for (int i = 1; s[i] != '\"'; i++, j++) {
- if (s[i] == '\\') {
- if (s[i + 1] == 'n')
- n[j] = '\n';
- i++;
- } else {
- n[j] = s[i];
- }
- }
- n[j] = '\0';
- return n;
-}
-
+++ /dev/null
-/**
- * @file string.h
- * Provides string.h from stdlib, plus some extra functions.
- *
- * Copyright (C) 2018 Clyne Sullivan
- *
- * 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-#ifndef STRING_H_
-#define STRING_H_
-
-#include <string.h>
-
-#ifndef size_t
-typedef unsigned int size_t;
-#endif
-
-/**
- * Clones a string of a given size into a malloc'd buffer.
- * @param s the string to clone
- * @param c the number of characters to copy
- * @return the malloc'd copy
- */
-char *strnclone(const char *s, size_t c);
-
-/**
- * Clones a string into a malloc'd buffer.
- * @param s the string to clone
- * @return the malloc'd copy
- */
-char *strclone(const char *s);
-
-/**
- * 'Fixes' a string, by converting "\n" and others to '\n'.
- * @param s the string to fix
- * @return the fixed string, in a malloc'd buffer
- */
-char *fixstring(const char *s);
-
-#endif // STRING_H_
--- /dev/null
+/**
+ * @file string.c
+ * Provides string.h from stdlib, plus some extra functions.
+ *
+ * Copyright (C) 2018 Clyne Sullivan
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "string.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+char *strnclone(const char *s, size_t c)
+{
+ char *b = strncpy((char *)malloc(c + 1), s, c);
+ b[c] = '\0';
+ return b;
+}
+
+char *strclone(const char *s)
+{
+ return strnclone(s, strlen(s));
+}
+
+char *fixstring(const char *s)
+{
+ char *n = (char *)malloc(strlen(s) + 1 - 2);
+ int j = 0;
+ for (int i = 1; s[i] != '\"'; i++, j++) {
+ if (s[i] == '\\') {
+ if (s[i + 1] == 'n')
+ n[j] = '\n';
+ i++;
+ } else {
+ n[j] = s[i];
+ }
+ }
+ n[j] = '\0';
+ return n;
+}
+
--- /dev/null
+/**
+ * @file string.h
+ * Provides string.h from stdlib, plus some extra functions.
+ *
+ * Copyright (C) 2018 Clyne Sullivan
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef STRING_H_
+#define STRING_H_
+
+#include <stddef.h>
+#include <string.h>
+
+/**
+ * Clones a string of a given size into a malloc'd buffer.
+ * @param s the string to clone
+ * @param c the number of characters to copy
+ * @return the malloc'd copy
+ */
+char *strnclone(const char *s, size_t c);
+
+/**
+ * Clones a string into a malloc'd buffer.
+ * @param s the string to clone
+ * @return the malloc'd copy
+ */
+char *strclone(const char *s);
+
+/**
+ * 'Fixes' a string, by converting "\n" and others to '\n'.
+ * @param s the string to fix
+ * @return the fixed string, in a malloc'd buffer
+ */
+char *fixstring(const char *s);
+
+#endif // STRING_H_
v->tmp = 1;
}
v->type = STRING;
- v->value.p = (uint32_t)strclone(s);
+ v->value.p = (size_t)strclone(s);
return v;
}
v->tmp = 1;
v->type = n->type;
if (n->type == STRING)
- v->value.p = (uint32_t)strclone((char *)n->value.p);
+ v->value.p = (size_t)strclone((char *)n->value.p);
else
v->value.p = n->value.p;
return v;
#define VARIABLE_H_
#include <stdint.h>
+#include <stddef.h>
/**
* Data for a script variable.
uint8_t tmp :1; /**< If zero, variable cannot be free'd */
uint8_t type :3; /**< The variable's type */
uint8_t unused :4; /**< Unused... */
- uint8_t array; /**< ">0?" -> array w/ this size */
+ uint8_t array; /**< Variable is array if >0, this defines array size */
union {
float f;
- uint32_t p;
+ size_t p;
} value; /**< The variable's value, either float or a pointer */
} variable;
variable *varclone(variable *n);
#endif // VARIABLE_H_
+