aboutsummaryrefslogtreecommitdiff
path: root/stdlib
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-10-28 13:53:15 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-10-28 13:53:15 -0400
commit9c302fdc34403f46572d9524309617888ba816bb (patch)
tree58ea7faf390536503de114cf2889ed85ba60df7b /stdlib
parentc632a72486d347e7ef30c0b7890e2045ed42b903 (diff)
parentce2aebe91085f987aab31bd2a49820fb605cf386 (diff)
Merge branch 'main' into internal-textsinternal-texts
Diffstat (limited to 'stdlib')
-rw-r--r--stdlib/datetime.c62
-rw-r--r--stdlib/datetime.h10
-rw-r--r--stdlib/paths.c8
-rw-r--r--stdlib/patterns.c30
-rw-r--r--stdlib/patterns.h2
-rw-r--r--stdlib/shell.c1
-rw-r--r--stdlib/stdlib.c2
-rw-r--r--stdlib/text.c3
-rw-r--r--stdlib/text.h3
-rw-r--r--stdlib/threads.c1
-rw-r--r--stdlib/tomo.h2
11 files changed, 98 insertions, 26 deletions
diff --git a/stdlib/datetime.c b/stdlib/datetime.c
index 9fa4f8cd..98c23a8e 100644
--- a/stdlib/datetime.c
+++ b/stdlib/datetime.c
@@ -124,6 +124,68 @@ public void DateTime$get(
if (weekday) *weekday = I(info.tm_wday + 1);
}
+public Int_t DateTime$year(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_year + 1900);
+}
+
+public Int_t DateTime$month(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_mon + 1);
+}
+
+public Int_t DateTime$day_of_week(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_wday + 1);
+}
+
+public Int_t DateTime$day_of_month(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_mday);
+}
+
+public Int_t DateTime$day_of_year(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_yday);
+}
+
+public Int_t DateTime$hour(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_hour);
+}
+
+public Int_t DateTime$minute(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_min);
+}
+
+public Int_t DateTime$second(DateTime_t dt, OptionalText_t timezone)
+{
+ struct tm info = {};
+ WITH_TIMEZONE(timezone, localtime_r(&dt.tv_sec, &info));
+ return I(info.tm_sec);
+}
+
+public Int_t DateTime$nanosecond(DateTime_t dt, OptionalText_t timezone)
+{
+ (void)timezone;
+ return I(dt.tv_usec);
+}
+
public Text_t DateTime$format(DateTime_t dt, Text_t fmt, OptionalText_t timezone)
{
struct tm info;
diff --git a/stdlib/datetime.h b/stdlib/datetime.h
index 96669aa3..ccbc5190 100644
--- a/stdlib/datetime.h
+++ b/stdlib/datetime.h
@@ -18,7 +18,15 @@ DateTime_t DateTime$after(DateTime_t dt, double seconds, double minutes, double
CONSTFUNC double DateTime$seconds_till(DateTime_t now, DateTime_t then);
CONSTFUNC double DateTime$minutes_till(DateTime_t now, DateTime_t then);
CONSTFUNC double DateTime$hours_till(DateTime_t now, DateTime_t then);
-void DateTime$get(DateTime_t dt, Int_t *year, Int_t *month, Int_t *day, Int_t *hour, Int_t *minute, Int_t *second, Int_t *nanosecond, Int_t *weekday, OptionalText_t timezone);
+Int_t DateTime$year(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$month(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$day_of_week(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$day_of_month(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$day_of_year(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$hour(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$minute(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$second(DateTime_t dt, OptionalText_t timezone);
+Int_t DateTime$nanosecond(DateTime_t dt, OptionalText_t timezone);
Text_t DateTime$format(DateTime_t dt, Text_t fmt, OptionalText_t timezone);
Text_t DateTime$date(DateTime_t dt, OptionalText_t timezone);
Text_t DateTime$time(DateTime_t dt, bool seconds, bool am_pm, OptionalText_t timezone);
diff --git a/stdlib/paths.c b/stdlib/paths.c
index 8acc34ff..e8a1e1f6 100644
--- a/stdlib/paths.c
+++ b/stdlib/paths.c
@@ -439,9 +439,11 @@ public Text_t Path$write_unique_bytes(Path_t path, Array_t bytes)
char buf[PATH_MAX] = {};
strcpy(buf, path_str);
- int64_t suffixlen = 0;
- (void)Text$find(path, Pattern("{0+!X}{end}"), I(1), &suffixlen);
- if (suffixlen < 0) suffixlen = 0;
+ // Count the number of trailing characters leading up to the last "X"
+ // (e.g. "foo_XXXXXX.tmp" would yield suffixlen = 4)
+ size_t suffixlen = 0;
+ while (suffixlen < len && buf[len - 1 - suffixlen] != 'X')
+ ++suffixlen;
int fd = mkstemps(buf, suffixlen);
if (fd == -1)
diff --git a/stdlib/patterns.c b/stdlib/patterns.c
index 701aff9c..6acb58a2 100644
--- a/stdlib/patterns.c
+++ b/stdlib/patterns.c
@@ -67,7 +67,7 @@ static inline bool match_str(TextIter_t *state, int64_t *i, const char *str)
static inline bool match_property(TextIter_t *state, int64_t *i, uc_property_t prop)
{
if (*i >= state->text.length) return false;
- ucs4_t grapheme = Text$get_main_grapheme_fast(state, *i);
+ uint32_t grapheme = Text$get_main_grapheme_fast(state, *i);
// TODO: check every codepoint in the cluster?
if (uc_is_property(grapheme, prop)) {
*i += 1;
@@ -80,8 +80,8 @@ static int64_t parse_int(TextIter_t *state, int64_t *i)
{
int64_t value = 0;
for (;; *i += 1) {
- ucs4_t grapheme = Text$get_main_grapheme_fast(state, *i);
- int digit = uc_digit_value((ucs4_t)grapheme);
+ uint32_t grapheme = Text$get_main_grapheme_fast(state, *i);
+ int digit = uc_digit_value(grapheme);
if (digit < 0) break;
if (value >= INT64_MAX/10) break;
value = 10*value + digit;
@@ -143,8 +143,8 @@ static int64_t match_email(TextIter_t *state, int64_t index)
// dns-label = 1-63 ([a-zA-Z0-9-] | non-ascii)
if (index > 0) {
- ucs4_t prev_codepoint = Text$get_main_grapheme_fast(state, index - 1);
- if (uc_is_property_alphabetic((ucs4_t)prev_codepoint))
+ uint32_t prev_codepoint = Text$get_main_grapheme_fast(state, index - 1);
+ if (uc_is_property_alphabetic(prev_codepoint))
return -1;
}
@@ -310,7 +310,7 @@ static int64_t match_uri(TextIter_t *state, int64_t index)
if (index > 0) {
// Don't match if we're not at a word edge:
- ucs4_t prev_codepoint = Text$get_main_grapheme_fast(state, index - 1);
+ uint32_t prev_codepoint = Text$get_main_grapheme_fast(state, index - 1);
if (uc_is_property_alphabetic(prev_codepoint))
return -1;
}
@@ -407,7 +407,7 @@ static int64_t match_newline(TextIter_t *state, int64_t index)
if (index >= state->text.length)
return -1;
- ucs4_t grapheme = index >= state->text.length ? 0 : Text$get_main_grapheme_fast(state, index);
+ uint32_t grapheme = index >= state->text.length ? 0 : Text$get_main_grapheme_fast(state, index);
if (grapheme == '\n')
return 1;
if (grapheme == '\r' && Text$get_grapheme_fast(state, index + 1) == '\n')
@@ -796,14 +796,14 @@ static int64_t _find(Text_t text, Pattern_t pattern, int64_t first, int64_t last
return -1;
}
-public Int_t Text$find(Text_t text, Pattern_t pattern, Int_t from_index, int64_t *match_length)
+public Int_t Text$find(Text_t text, Pattern_t pattern, Int_t from_index)
{
int64_t first = Int_to_Int64(from_index, false);
if (first == 0) fail("Invalid index: 0");
if (first < 0) first = text.length + first + 1;
if (first > text.length || first < 1)
return I(0);
- int64_t found = _find(text, pattern, first-1, text.length-1, match_length);
+ int64_t found = _find(text, pattern, first-1, text.length-1, NULL);
return I(found+1);
}
@@ -1081,17 +1081,17 @@ public Array_t Text$split(Text_t text, Pattern_t pattern)
Array_t chunks = {};
- Int_t i = I_small(1);
+ int64_t i = 0;
for (;;) {
int64_t len = 0;
- Int_t found = Text$find(text, pattern, i, &len);
- if (I_is_zero(found)) break;
- Text_t chunk = Text$slice(text, i, Int$minus(found, I_small(1)));
+ int64_t found = _find(text, pattern, i, text.length-1, &len);
+ if (found < 0) break;
+ Text_t chunk = Text$slice(text, I(i+1), I(found));
Array$insert(&chunks, &chunk, I_small(0), sizeof(Text_t));
- i = Int$plus(found, I(MAX(len, 1)));
+ i = found + MAX(len, 1);
}
- Text_t last_chunk = Text$slice(text, i, I(text.length));
+ Text_t last_chunk = Text$slice(text, I(i+1), I(text.length));
Array$insert(&chunks, &last_chunk, I_small(0), sizeof(Text_t));
return chunks;
diff --git a/stdlib/patterns.h b/stdlib/patterns.h
index c1246b1e..9cfbcd6b 100644
--- a/stdlib/patterns.h
+++ b/stdlib/patterns.h
@@ -18,7 +18,7 @@ Pattern_t Pattern$escape_text(Text_t text);
Text_t Text$replace_all(Text_t text, Table_t replacements, Pattern_t backref_pat, bool recursive);
Array_t Text$split(Text_t text, Pattern_t pattern);
Text_t Text$trim(Text_t text, Pattern_t pattern, bool trim_left, bool trim_right);
-Int_t Text$find(Text_t text, Pattern_t pattern, Int_t i, int64_t *match_length);
+Int_t Text$find(Text_t text, Pattern_t pattern, Int_t i);
Array_t Text$find_all(Text_t text, Pattern_t pattern);
PUREFUNC bool Text$has(Text_t text, Pattern_t pattern);
Array_t Text$matches(Text_t text, Pattern_t pattern);
diff --git a/stdlib/shell.c b/stdlib/shell.c
index d2d0f78a..68c61115 100644
--- a/stdlib/shell.c
+++ b/stdlib/shell.c
@@ -2,6 +2,7 @@
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
+#include <unistr.h>
#include "arrays.h"
#include "integers.h"
diff --git a/stdlib/stdlib.c b/stdlib/stdlib.c
index 34acc828..d90f5748 100644
--- a/stdlib/stdlib.c
+++ b/stdlib/stdlib.c
@@ -441,7 +441,7 @@ public void end_test(const void *expr, const TypeInfo_t *type, const char *expec
Text_t expr_plain = USE_COLOR ? generic_as_text(expr, false, type) : expr_text;
bool success = Text$equal(&expr_plain, &expected_text);
if (!success) {
- Int_t colon = Text$find(expected_text, Text(":"), I_small(1), NULL);
+ Int_t colon = Text$find(expected_text, Text(":"), I_small(1));
if (colon.small != I_small(0).small) {
Text_t with_type = Text$concat(expr_plain, Text(" : "), type_name);
success = Text$equal(&with_type, &expected_text);
diff --git a/stdlib/text.c b/stdlib/text.c
index 0af95413..deca024a 100644
--- a/stdlib/text.c
+++ b/stdlib/text.c
@@ -56,6 +56,7 @@
#include <stdlib.h>
#include <sys/param.h>
+#include <unistr.h>
#include <unicase.h>
#include <unictype.h>
#include <unigbrk.h>
@@ -846,7 +847,7 @@ public int32_t Text$get_grapheme_fast(TextIter_t *state, int64_t index)
return 0;
}
-public ucs4_t Text$get_main_grapheme_fast(TextIter_t *state, int64_t index)
+public uint32_t Text$get_main_grapheme_fast(TextIter_t *state, int64_t index)
{
return MAIN_GRAPHEME_CODEPOINT(Text$get_grapheme_fast(state, index));
}
diff --git a/stdlib/text.h b/stdlib/text.h
index 43eee1cc..e915eefd 100644
--- a/stdlib/text.h
+++ b/stdlib/text.h
@@ -6,7 +6,6 @@
#include <stdbool.h>
#include <printf.h>
#include <stdint.h>
-#include <unistr.h>
#include "datatypes.h"
#include "integers.h"
@@ -55,7 +54,7 @@ Array_t Text$lines(Text_t text);
Text_t Text$join(Text_t glue, Array_t pieces);
Text_t Text$repeat(Text_t text, Int_t count);
int32_t Text$get_grapheme_fast(TextIter_t *state, int64_t index);
-ucs4_t Text$get_main_grapheme_fast(TextIter_t *state, int64_t index);
+uint32_t Text$get_main_grapheme_fast(TextIter_t *state, int64_t index);
static inline int32_t Text$get_grapheme(Text_t text, int64_t index)
{
diff --git a/stdlib/threads.c b/stdlib/threads.c
index bd9f017e..0cb47e1b 100644
--- a/stdlib/threads.c
+++ b/stdlib/threads.c
@@ -11,6 +11,7 @@
#include <sys/param.h>
#include "arrays.h"
+#include "datatypes.h"
#include "text.h"
#include "threads.h"
#include "types.h"
diff --git a/stdlib/tomo.h b/stdlib/tomo.h
index 515bb8da..64a9979b 100644
--- a/stdlib/tomo.h
+++ b/stdlib/tomo.h
@@ -3,8 +3,6 @@
// All of the different builtin modules can be included by including this one
// import
-#include <gc.h>
-#include <gmp.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/param.h>