aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/enums.c4
-rw-r--r--src/parse.c8
-rw-r--r--src/repl.c6
-rw-r--r--src/stdlib/files.c19
-rw-r--r--src/stdlib/integers.h1
-rw-r--r--src/stdlib/paths.c4
-rw-r--r--src/stdlib/print.h9
-rw-r--r--src/stdlib/stdlib.c2
-rw-r--r--src/stdlib/util.c26
-rw-r--r--src/stdlib/util.h3
10 files changed, 31 insertions, 51 deletions
diff --git a/src/enums.c b/src/enums.c
index 06af0df3..eeeff19d 100644
--- a/src/enums.c
+++ b/src/enums.c
@@ -23,7 +23,7 @@ CORD compile_enum_typeinfo(env_t *env, ast_t *ast)
for (tag_ast_t *tag = def->tags; tag; tag = tag->next) {
if (!tag->fields) continue;
- const char *tag_name = heap_strf("%s$%s", def->name, tag->name);
+ const char *tag_name = String(def->name, "$", tag->name);
type_t *tag_type = Table$str_get(*env->types, tag_name);
assert(tag_type && tag_type->tag == StructType);
member_typeinfos = CORD_all(
@@ -41,7 +41,7 @@ CORD compile_enum_typeinfo(env_t *env, ast_t *ast)
full_name, type_size(t), type_align(t), metamethods, def->name, num_tags);
for (tag_ast_t *tag = def->tags; tag; tag = tag->next) {
- const char *tag_type_name = heap_strf("%s$%s", def->name, tag->name);
+ const char *tag_type_name = String(def->name, "$", tag->name);
type_t *tag_type = Table$str_get(*env->types, tag_type_name);
if (tag_type && Match(tag_type, StructType)->fields)
typeinfo = CORD_all(typeinfo, "{\"", tag->name, "\", ", compile_type_info(tag_type), "}, ");
diff --git a/src/parse.c b/src/parse.c
index a3c68410..04e35953 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -246,7 +246,7 @@ static const char *unescape(parse_ctx_t *ctx, const char **out) {
if (escape[2+len] != ']')
parser_err(ctx, escape, escape + 2 + len, "Missing closing ']'");
*endpos = escape + 3 + len;
- return heap_strf("\033[%.*sm", len, &escape[2]);
+ return String("\033[", string_slice(&escape[2], len), "m");
} else if (escape[1] == '{') {
// Unicode codepoints by name
size_t len = strcspn(&escape[2], "\r\n}");
@@ -583,7 +583,7 @@ type_ast_t *parse_type_name(parse_ctx_t *ctx, const char *pos) {
if (!match(&next, ".")) break;
const char *next_id = get_id(&next);
if (!next_id) break;
- id = heap_strf("%s.%s", id, next_id);
+ id = String(id, ".", next_id);
pos = next;
}
return NewTypeAST(ctx->file, start, pos, VarTypeAST, .name=id);
@@ -852,7 +852,7 @@ ast_t *parse_field_suffix(parse_ctx_t *ctx, ast_t *lhs) {
bool dollar = match(&pos, "$");
const char* field = get_id(&pos);
if (!field) return NULL;
- if (dollar) field = heap_strf("$%s", field);
+ if (dollar) field = String("$", field);
return NewAST(ctx->file, lhs->start, pos, FieldAccess, .fielded=lhs, .field=field);
}
@@ -1349,7 +1349,7 @@ PARSER(parse_path) {
len += 1;
}
pos += len + 1;
- char *path = heap_strf("%.*s", (int)len, path_start);
+ char *path = String(string_slice(path_start, .length=len));
for (char *src = path, *dest = path; ; ) {
if (src[0] == '\\') {
*(dest++) = src[1];
diff --git a/src/repl.c b/src/repl.c
index ae12427a..2f5c60f6 100644
--- a/src/repl.c
+++ b/src/repl.c
@@ -63,14 +63,14 @@ void repl(void)
code = GC_strdup(line);
while ((len=getline(&line, &buf_size, stdin)) >= 0) {
if (len == 1) break;
- code = heap_strf("%s%s", code, line);
+ code = String(code, line);
printf("\x1b[33;1m..\x1b[m ");
fflush(stdout);
}
} else {
- code = heap_strf("func main(): >> %s", code);
+ code = String("func main(): >> ", code);
}
- ast_t *ast = parse_file(heap_strf("<code>%s", code), &on_err);
+ ast_t *ast = parse_file(String("<code>", code), &on_err);
ast_t *doctest = Match(Match(Match(ast, Block)->statements->ast, FunctionDef)->body, Block)->statements->ast;
if (doctest->tag == DocTest) doctest->__data.DocTest.skip_source = 1;
run(env, doctest);
diff --git a/src/stdlib/files.c b/src/stdlib/files.c
index 88265099..fa063697 100644
--- a/src/stdlib/files.c
+++ b/src/stdlib/files.c
@@ -15,6 +15,7 @@
#include <sys/param.h>
#include "files.h"
+#include "print.h"
#include "util.h"
static const int tabstop = 4;
@@ -28,11 +29,11 @@ public char *resolve_path(const char *path, const char *relative_to, const char
// it was found in:
char buf[PATH_MAX] = {0};
if (streq(path, "~") || starts_with(path, "~/")) {
- char *resolved = realpath(heap_strf("%s%s", getenv("HOME"), path+1), buf);
+ char *resolved = realpath(String(getenv("HOME"), path+1), buf);
if (resolved) return GC_strdup(resolved);
} else if (streq(path, ".") || starts_with(path, "./") || starts_with(path, "../")) {
char *relative_dir = dirname(GC_strdup(relative_to));
- char *resolved = realpath(heap_strf("%s/%s", relative_dir, path), buf);
+ char *resolved = realpath(String(relative_dir, "/", relative_dir, path), buf);
if (resolved) return GC_strdup(resolved);
} else if (path[0] == '/') {
// Absolute path:
@@ -45,19 +46,19 @@ public char *resolve_path(const char *path, const char *relative_to, const char
char *copy = GC_strdup(system_path);
for (char *dir, *pos = copy; (dir = strtok(pos, ":")); pos = NULL) {
if (dir[0] == '/') {
- char *resolved = realpath(heap_strf("%s/%s", dir, path), buf);
+ char *resolved = realpath(String(dir, "/", path), buf);
if (resolved) return GC_strdup(resolved);
} else if (dir[0] == '~' && (dir[1] == '\0' || dir[1] == '/')) {
- char *resolved = realpath(heap_strf("%s%s/%s", getenv("HOME"), dir+1, path), buf);
+ char *resolved = realpath(String(getenv("HOME"), dir+1, "/", path), buf);
if (resolved) return GC_strdup(resolved);
} else if (streq(dir, ".") || strncmp(dir, "./", 2) == 0) {
- char *resolved = realpath(heap_strf("%s/%s", relative_dir, path), buf);
+ char *resolved = realpath(String(relative_dir, "/", path), buf);
if (resolved) return GC_strdup(resolved);
} else if (streq(dir, ".") || streq(dir, "..") || strncmp(dir, "./", 2) == 0 || strncmp(dir, "../", 3) == 0) {
- char *resolved = realpath(heap_strf("%s/%s/%s", relative_dir, dir, path), buf);
+ char *resolved = realpath(String(relative_dir, "/", dir, "/", path), buf);
if (resolved) return GC_strdup(resolved);
} else {
- char *resolved = realpath(heap_strf("%s/%s", dir, path), buf);
+ char *resolved = realpath(String(dir, "/", path), buf);
if (resolved) return GC_strdup(resolved);
}
}
@@ -196,11 +197,11 @@ public const char *get_line(file_t *f, int64_t line_number)
}
//
-// Return a value like /foo:line:col
+// Return a value like /foo:line.col
//
public const char *get_file_pos(file_t *f, const char *p)
{
- return heap_strf("%s:%ld:%ld", f->filename, get_line_number(f, p), get_line_column(f, p));
+ return String(f->filename, ":", get_line_number(f, p), ".", get_line_column(f, p));
}
static int fputc_column(FILE *out, char c, char print_char, int *column)
diff --git a/src/stdlib/integers.h b/src/stdlib/integers.h
index a057327b..43fc2217 100644
--- a/src/stdlib/integers.h
+++ b/src/stdlib/integers.h
@@ -88,7 +88,6 @@ void Int64$deserialize(FILE *in, void *outval, Array_t*, const TypeInfo_t*);
void Int32$serialize(const void *obj, FILE *out, Table_t*, const TypeInfo_t*);
void Int32$deserialize(FILE *in, void *outval, Array_t*, const TypeInfo_t*);
-int Int$print(FILE *f, Int_t i);
Text_t Int$as_text(const void *i, bool colorize, const TypeInfo_t *type);
Text_t Int$value_as_text(Int_t i);
PUREFUNC uint64_t Int$hash(const void *x, const TypeInfo_t *type);
diff --git a/src/stdlib/paths.c b/src/stdlib/paths.c
index 3f27aef7..7a5346f5 100644
--- a/src/stdlib/paths.c
+++ b/src/stdlib/paths.c
@@ -17,7 +17,6 @@
#include <unistd.h>
#include <unistr.h>
-#include "print.h"
#include "arrays.h"
#include "enums.h"
#include "files.h"
@@ -28,6 +27,7 @@
#include "text.h"
#include "types.h"
#include "util.h"
+#include "print.h"
// Use inline version of the siphash code for performance:
#include "siphash.h"
@@ -491,7 +491,7 @@ static Array_t _filtered_children(Path_t path, bool include_hidden, mode_t filte
if (streq(dir->d_name, ".") || streq(dir->d_name, ".."))
continue;
- const char *child_str = heap_strf("%.*s/%s", path_len, path_str, dir->d_name);
+ const char *child_str = String(string_slice(path_str, path_len), "/", dir->d_name);
struct stat sb;
if (stat(child_str, &sb) != 0)
continue;
diff --git a/src/stdlib/print.h b/src/stdlib/print.h
index 41b316e6..0b911ed6 100644
--- a/src/stdlib/print.h
+++ b/src/stdlib/print.h
@@ -85,6 +85,12 @@ typedef struct {
} quoted_t;
#define quoted(s) ((quoted_t){s})
+typedef struct {
+ const char *str;
+ size_t length;
+} string_slice_t;
+#define string_slice(...) ((string_slice_t){__VA_ARGS__})
+
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#define FMT64 "ll"
#else
@@ -105,6 +111,7 @@ PRINT_FN _print_bool(FILE *f, bool b) { return fputs(b ? hl("yes") : hl("no"), f
PRINT_FN _print_str(FILE *f, const char *s) { return fputs(s, f); }
int _print_char(FILE *f, char c);
int _print_quoted(FILE *f, quoted_t quoted);
+PRINT_FN _print_string_slice(FILE *f, string_slice_t slice) { return fwrite(slice.str, 1, slice.length, f); }
PRINT_FN _print_hex(FILE *f, hex_format_t hex) {
return fprintf(f, hex.no_prefix ? (hex.uppercase ? hl("%0*"FMT64"X") : hl("%0*"FMT64"x")) : (hex.uppercase ? hl("0x%0*"FMT64"X") : hl("%#0*"FMT64"x")), hex.digits, hex.n);
}
@@ -118,6 +125,7 @@ PRINT_FN _print_num_format(FILE *f, num_format_t num) {
extern int Text$print(FILE *stream, Text_t text);
extern int Path$print(FILE *stream, Path_t path);
+extern int Int$print(FILE *f, Int_t i);
#ifndef _fprint1
#define _fprint1(f, x) _Generic((x), \
char*: _print_str, \
@@ -138,6 +146,7 @@ extern int Path$print(FILE *stream, Path_t path);
oct_format_t: _print_oct, \
num_format_t: _print_num_format, \
quoted_t: _print_quoted, \
+ string_slice_t: _print_string_slice, \
Text_t: Text$print, \
Path_t: Path$print, \
Int_t: Int$print, \
diff --git a/src/stdlib/stdlib.c b/src/stdlib/stdlib.c
index 80c53b68..8d3a8081 100644
--- a/src/stdlib/stdlib.c
+++ b/src/stdlib/stdlib.c
@@ -491,7 +491,7 @@ public void print_stack_trace(FILE *out, int start, int stop)
char *paren = strings[i] + strcspn(strings[i], "(");
char *addr_end = paren + 1 + strcspn(paren + 1, ")");
ptrdiff_t offset = strtol(paren + 1, &addr_end, 16) - 1;
- const char *cmd = heap_strf("addr2line -e %.*s -is +0x%x", strcspn(filename, "("), filename, offset);
+ const char *cmd = String("addr2line -e ", string_slice(filename, strcspn(filename, "(")), " -is +", hex((uint64_t)offset));
FILE *fp = popen(cmd, "r");
OptionalText_t fn_name = get_function_name(stack[i]);
const char *src_filename = NULL;
diff --git a/src/stdlib/util.c b/src/stdlib/util.c
deleted file mode 100644
index 1fe33dfa..00000000
--- a/src/stdlib/util.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// Built-in utility functions
-#include <ctype.h>
-#include <gc.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "text.h"
-#include "util.h"
-
-__attribute__((format(printf, 1, 2)))
-public char *heap_strf(const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- char *tmp = NULL;
- int len = vasprintf(&tmp, fmt, args);
- if (len < 0) return NULL;
- va_end(args);
- char *ret = GC_strndup(tmp, (size_t)len);
- free(tmp);
- return ret;
-}
-
-// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
diff --git a/src/stdlib/util.h b/src/stdlib/util.h
index 6f79bed6..45bf1d7b 100644
--- a/src/stdlib/util.h
+++ b/src/stdlib/util.h
@@ -55,7 +55,4 @@
#define MACROLIKE extern inline __attribute__((gnu_inline, always_inline))
#endif
-__attribute__((format(printf, 1, 2)))
-char *heap_strf(const char *fmt, ...);
-
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0