mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 20:11:17 +00:00
Compare commits
1 Commits
v0.7.7
...
named_argu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7f11a6cf4 |
@@ -78,13 +78,13 @@ fn usz! AnyList.to_format(&self, Formatter* formatter) @dynamic
|
||||
|
||||
fn String AnyList.to_new_string(&self, Allocator allocator = null) @dynamic
|
||||
{
|
||||
return string::format("%s", *self, .allocator = allocator ?: allocator::heap());
|
||||
return string::format("%s", *self, allocator: allocator ?: allocator::heap());
|
||||
}
|
||||
|
||||
|
||||
fn String AnyList.to_string(&self, Allocator allocator) @dynamic
|
||||
{
|
||||
return string::format("%s", *self, .allocator = allocator);
|
||||
return string::format("%s", *self, allocator: allocator);
|
||||
}
|
||||
|
||||
fn String AnyList.to_tstring(&self) => string::tformat("%s", *self);
|
||||
|
||||
@@ -41,12 +41,12 @@ fn usz! ElasticArray.to_format(&self, Formatter* formatter) @dynamic
|
||||
|
||||
fn String ElasticArray.to_string(&self, Allocator allocator) @dynamic
|
||||
{
|
||||
return string::format("%s", *self, .allocator = allocator);
|
||||
return string::format("%s", *self, allocator: allocator);
|
||||
}
|
||||
|
||||
fn String ElasticArray.to_new_string(&self, Allocator allocator = nul) @dynamic
|
||||
{
|
||||
return string::format("%s", *self, .allocator = allocator ?: allocator::heap());
|
||||
return string::format("%s", *self, allocator: allocator ?: allocator::heap());
|
||||
}
|
||||
|
||||
fn String ElasticArray.to_tstring(&self)
|
||||
|
||||
@@ -27,12 +27,12 @@ fn usz! EnumMap.to_format(&self, Formatter* formatter) @dynamic
|
||||
|
||||
fn String EnumMap.to_string(&self, Allocator allocator) @dynamic
|
||||
{
|
||||
return string::format("%s", *self, .allocator = allocator);
|
||||
return string::format("%s", *self, allocator: allocator);
|
||||
}
|
||||
|
||||
fn String EnumMap.to_new_string(&self, Allocator allocator = null) @dynamic
|
||||
{
|
||||
return string::format("%s", *self, .allocator = allocator ?: allocator::heap());
|
||||
return string::format("%s", *self, allocator: allocator ?: allocator::heap());
|
||||
}
|
||||
|
||||
fn String EnumMap.to_tstring(&self) @dynamic
|
||||
|
||||
@@ -143,12 +143,12 @@ fn usz! EnumSet.to_format(&set, Formatter* formatter) @dynamic
|
||||
|
||||
fn String EnumSet.to_new_string(&set, Allocator allocator = allocator::heap()) @dynamic
|
||||
{
|
||||
return string::format("%s", *set, .allocator = allocator);
|
||||
return string::format("%s", *set, allocator: allocator);
|
||||
}
|
||||
|
||||
fn String EnumSet.to_string(&set, Allocator allocator) @dynamic
|
||||
{
|
||||
return string::format("%s", *set, .allocator = allocator);
|
||||
return string::format("%s", *set, allocator: allocator);
|
||||
}
|
||||
|
||||
fn String EnumSet.to_tstring(&set) @dynamic
|
||||
|
||||
@@ -102,7 +102,7 @@ fn usz! List.to_format(&self, Formatter* formatter) @dynamic
|
||||
|
||||
fn String List.to_new_string(&self, Allocator allocator = allocator::heap()) @dynamic
|
||||
{
|
||||
return string::format("%s", *self, .allocator = allocator);
|
||||
return string::format("%s", *self, allocator: allocator);
|
||||
}
|
||||
|
||||
fn String List.to_tstring(&self)
|
||||
@@ -352,7 +352,7 @@ fn void List.ensure_capacity(&self, usz min_capacity) @local
|
||||
|
||||
min_capacity = math::next_power_of_2(min_capacity);
|
||||
$if type_is_overaligned():
|
||||
self.entries = allocator::realloc_aligned(self.allocator, self.entries, Type.sizeof * min_capacity, .alignment = Type[1].alignof)!!;
|
||||
self.entries = allocator::realloc_aligned(self.allocator, self.entries, Type.sizeof * min_capacity, alignment: Type[1].alignof)!!;
|
||||
$else
|
||||
self.entries = allocator::realloc(self.allocator, self.entries, Type.sizeof * min_capacity);
|
||||
$endif;
|
||||
|
||||
@@ -53,7 +53,7 @@ fn Map new_from_map(Map other_map, Allocator allocator = null)
|
||||
MapImpl* other_map_impl = (MapImpl*)other_map;
|
||||
if (!other_map_impl)
|
||||
{
|
||||
if (allocator) return new(.allocator = allocator);
|
||||
if (allocator) return new(allocator: allocator);
|
||||
return null;
|
||||
}
|
||||
MapImpl* map = (MapImpl*)new(other_map_impl.table.len, other_map_impl.load_factor, allocator ?: allocator::heap());
|
||||
|
||||
@@ -156,7 +156,7 @@ fn void Object.init_map_if_needed(&self) @private
|
||||
if (self.is_empty())
|
||||
{
|
||||
self.type = ObjectInternalMap.typeid;
|
||||
self.map.new_init(.allocator = self.allocator);
|
||||
self.map.new_init(allocator: self.allocator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ fn void Object.init_array_if_needed(&self) @private
|
||||
if (self.is_empty())
|
||||
{
|
||||
self.type = ObjectInternalList.typeid;
|
||||
self.array.new_init(.allocator = self.allocator);
|
||||
self.array.new_init(allocator: self.allocator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,12 +31,12 @@ fn Type Range.get(&self, usz index) @operator([])
|
||||
|
||||
fn String Range.to_new_string(&self, Allocator allocator = allocator::heap()) @dynamic @deprecated
|
||||
{
|
||||
return string::format("[%s..%s]", self.start, self.end, .allocator = allocator);
|
||||
return string::format("[%s..%s]", self.start, self.end, allocator: allocator);
|
||||
}
|
||||
|
||||
fn String Range.to_string(&self, Allocator allocator) @dynamic
|
||||
{
|
||||
return string::format("[%s..%s]", self.start, self.end, .allocator = allocator);
|
||||
return string::format("[%s..%s]", self.start, self.end, allocator: allocator);
|
||||
}
|
||||
|
||||
fn String Range.to_tstring(&self)
|
||||
@@ -78,7 +78,7 @@ fn String ExclusiveRange.to_new_string(&self, Allocator allocator = null) @dynam
|
||||
|
||||
fn String ExclusiveRange.to_string(&self, Allocator allocator) @dynamic
|
||||
{
|
||||
return string::format("[%s..<%s]", self.start, self.end, .allocator = allocator);
|
||||
return string::format("[%s..<%s]", self.start, self.end, allocator: allocator);
|
||||
}
|
||||
|
||||
fn String ExclusiveRange.to_tstring(&self)
|
||||
|
||||
@@ -34,7 +34,7 @@ struct TrackingAllocator (Allocator)
|
||||
fn void TrackingAllocator.init(&self, Allocator allocator)
|
||||
{
|
||||
*self = { .inner_allocator = allocator };
|
||||
self.map.new_init(.allocator = allocator);
|
||||
self.map.new_init(allocator: allocator);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -123,7 +123,7 @@ fn void panicf(String fmt, String file, String function, uint line, args...)
|
||||
@stack_mem(512; Allocator allocator)
|
||||
{
|
||||
DString s;
|
||||
s.new_init(.allocator = allocator);
|
||||
s.new_init(allocator: allocator);
|
||||
s.appendf(fmt, ...args);
|
||||
panic(s.str_view(), file, function, line);
|
||||
};
|
||||
|
||||
@@ -143,7 +143,7 @@ macro void free_aligned(Allocator allocator, void* ptr)
|
||||
$if env::TESTING:
|
||||
((char*)ptr)[0] = 0xBA;
|
||||
$endif
|
||||
allocator.release(ptr, .aligned = true);
|
||||
allocator.release(ptr, aligned: true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -66,7 +66,7 @@ macro String format(String fmt, ..., Allocator allocator)
|
||||
*
|
||||
* @param [in] fmt `The formatting string`
|
||||
**/
|
||||
macro String new_format(String fmt, ..., Allocator allocator = null) => format(fmt, $vasplat, .allocator = allocator ?: allocator::heap());
|
||||
macro String new_format(String fmt, ..., Allocator allocator = null) => format(fmt, $vasplat, allocator: allocator ?: allocator::heap());
|
||||
|
||||
/**
|
||||
* Return a temporary String created using the formatting function.
|
||||
|
||||
@@ -22,7 +22,7 @@ fn String[]! CsvReader.read_new_row_with_allocator(self, Allocator allocator = a
|
||||
{
|
||||
@pool(allocator)
|
||||
{
|
||||
return io::treadline(self.stream).split(self.separator, .allocator = allocator);
|
||||
return io::treadline(self.stream).split(self.separator, allocator: allocator);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ macro CsvReader.@each_row(self, int rows = int.max; @body(String[] row))
|
||||
if (err == IoError.EOF) return;
|
||||
return err?;
|
||||
}
|
||||
parts = s.split(sep, .allocator = mem);
|
||||
parts = s.split(sep, allocator: mem);
|
||||
};
|
||||
@body(parts);
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ import std::io, std::os;
|
||||
fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator allocator)
|
||||
{
|
||||
PathList list;
|
||||
list.new_init(.allocator = allocator);
|
||||
list.new_init(allocator: allocator);
|
||||
DIRPtr directory = posix::opendir(dir.str_view() ? dir.as_zstr() : (ZString)".");
|
||||
defer if (directory) posix::closedir(directory);
|
||||
if (!directory) return (path::is_dir(dir) ? IoError.CANNOT_READ_DIR : IoError.FILE_NOT_DIR)?;
|
||||
@@ -27,7 +27,7 @@ import std::time, std::os, std::io;
|
||||
fn PathList! native_ls(Path dir, bool no_dirs, bool no_symlinks, String mask, Allocator allocator)
|
||||
{
|
||||
PathList list;
|
||||
list.new_init(.allocator = allocator);
|
||||
list.new_init(allocator: allocator);
|
||||
|
||||
@pool(allocator)
|
||||
{
|
||||
|
||||
@@ -141,7 +141,7 @@ fn Path! new_win32_wstring(WString path, Allocator allocator = allocator::heap()
|
||||
{
|
||||
@pool(allocator)
|
||||
{
|
||||
return path::new(string::temp_from_wstring(path)!, .allocator = allocator);
|
||||
return path::new(string::temp_from_wstring(path)!, allocator: allocator);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@ fn bool! Path.walk(self, PathWalker w, void* data)
|
||||
@stack_mem(PATH_MAX; Allocator allocator)
|
||||
{
|
||||
Path abs = self.new_absolute(allocator)!;
|
||||
PathList files = new_ls(abs, .allocator = allocator)!;
|
||||
PathList files = new_ls(abs, allocator: allocator)!;
|
||||
foreach (f : files)
|
||||
{
|
||||
if (f.str_view() == "." || f.str_view() == "..") continue;
|
||||
|
||||
@@ -131,7 +131,7 @@ fn usz! ByteBuffer.available(&self) @inline @dynamic
|
||||
fn void! ByteBuffer.grow(&self, usz n)
|
||||
{
|
||||
n = math::next_power_of_2(n);
|
||||
char* p = allocator::realloc_aligned(self.allocator, self.bytes, n, .alignment = char.alignof)!;
|
||||
char* p = allocator::realloc_aligned(self.allocator, self.bytes, n, alignment: char.alignof)!;
|
||||
self.bytes = p[:n];
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ fn Path! new_get_config_dir(Allocator allocator = allocator::heap())
|
||||
String s = get_var_temp("XDG_CONFIG_HOME") ?? get_var_temp("HOME")!;
|
||||
const DIR = ".config";
|
||||
$endif
|
||||
return path::temp_new(s).new_append(DIR, .allocator = allocator);
|
||||
return path::temp_new(s).new_append(DIR, allocator: allocator);
|
||||
$endif
|
||||
};
|
||||
}
|
||||
|
||||
@@ -193,10 +193,10 @@ fn Backtrace! resolve_backtrace(void* addr, Win32_HANDLE process, Allocator allo
|
||||
ZString zname = (ZString)&name;
|
||||
if (!symGetLineFromAddr64(process, (Win32_ULONG64)addr - 1, &offset, &line))
|
||||
{
|
||||
backtrace.init((uptr)addr, zname.str_view(), module_name.str_view(), .allocator = allocator);
|
||||
backtrace.init((uptr)addr, zname.str_view(), module_name.str_view(), allocator: allocator);
|
||||
return backtrace;
|
||||
}
|
||||
String filename = ((ZString)line.fileName).str_view();
|
||||
backtrace.init((uptr)addr, zname.str_view(), module_name.str_view(), .file = filename, .line = line.lineNumber, .allocator = allocator);
|
||||
backtrace.init((uptr)addr, zname.str_view(), module_name.str_view(), file: filename, line: line.lineNumber, allocator: allocator);
|
||||
return backtrace;
|
||||
}
|
||||
|
||||
@@ -443,11 +443,19 @@ param_path
|
||||
| param_path param_path_element
|
||||
;
|
||||
|
||||
arg_name
|
||||
: IDENT
|
||||
| CT_TYPE_IDENT
|
||||
| HASH_IDENT
|
||||
| CT_IDENT
|
||||
;
|
||||
arg
|
||||
: param_path '=' expr
|
||||
| param_path
|
||||
| type
|
||||
| param_path '=' type
|
||||
| param_path
|
||||
| arg_name ':' expr
|
||||
| arg_name ':' type
|
||||
| type
|
||||
| expr
|
||||
| CT_VASPLAT '[' range_expr ']'
|
||||
| ELLIPSIS expr
|
||||
|
||||
@@ -611,9 +611,9 @@ typedef struct Decl_
|
||||
void *backend_value;
|
||||
void *tb_symbol;
|
||||
};
|
||||
AlignSize alignment;
|
||||
AlignSize offset;
|
||||
AlignSize padding;
|
||||
AlignSize alignment;
|
||||
struct CompilationUnit_ *unit;
|
||||
union
|
||||
{
|
||||
@@ -807,6 +807,13 @@ typedef struct
|
||||
Expr *value;
|
||||
} ExprDesignator;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
SourceSpan name_span;
|
||||
Expr *value;
|
||||
} ExprNamedArgument;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Decl *type;
|
||||
@@ -1093,6 +1100,7 @@ struct Expr_
|
||||
Decl *decl_expr; // 8
|
||||
Expr** designated_init_list; // 8
|
||||
ExprDesignator designator_expr; // 16
|
||||
ExprNamedArgument named_argument_expr;
|
||||
ExprEmbedExpr embed_expr; // 16
|
||||
Expr** exec_expr; // 8
|
||||
ExprAsmArg expr_asm_arg; // 24
|
||||
@@ -3147,7 +3155,7 @@ INLINE bool expr_poison(Expr *expr) { expr->expr_kind = EXPR_POISONED; expr->res
|
||||
|
||||
static inline void expr_list_set_span(Expr **expr, SourceSpan loc);
|
||||
static inline void exprid_set_span(ExprId expr_id, SourceSpan loc);
|
||||
INLINE void expr_set_span(Expr *expr, SourceSpan loc);
|
||||
static inline void expr_set_span(Expr *expr, SourceSpan loc);
|
||||
|
||||
static inline void const_init_set_span(ConstInitializer *init, SourceSpan loc)
|
||||
{
|
||||
@@ -3191,11 +3199,15 @@ static inline void const_init_set_span(ConstInitializer *init, SourceSpan loc)
|
||||
static inline void expr_list_set_span(Expr **expr, SourceSpan loc);
|
||||
static inline void exprid_set_span(ExprId expr_id, SourceSpan loc);
|
||||
|
||||
INLINE void expr_set_span(Expr *expr, SourceSpan loc)
|
||||
static inline void expr_set_span(Expr *expr, SourceSpan loc)
|
||||
{
|
||||
expr->span = loc;
|
||||
switch (expr->expr_kind)
|
||||
{
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
expr->named_argument_expr.name_span = loc;
|
||||
expr_set_span(expr->named_argument_expr.value, loc);
|
||||
return;
|
||||
case EXPR_CONST:
|
||||
switch (expr->const_expr.const_kind)
|
||||
{
|
||||
|
||||
@@ -294,6 +294,9 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr)
|
||||
case EXPR_OTHER_CONTEXT:
|
||||
MACRO_COPY_EXPR(expr->expr_other_context.inner);
|
||||
return expr;
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
MACRO_COPY_EXPR(expr->named_argument_expr.value);
|
||||
return expr;
|
||||
case EXPR_EMBED:
|
||||
MACRO_COPY_EXPR(expr->embed_expr.len);
|
||||
MACRO_COPY_EXPR(expr->embed_expr.filename);
|
||||
|
||||
@@ -793,6 +793,7 @@ typedef enum
|
||||
EXPR_MACRO_BODY,
|
||||
EXPR_MACRO_BODY_EXPANSION,
|
||||
EXPR_MEMBER_GET,
|
||||
EXPR_NAMED_ARGUMENT,
|
||||
EXPR_NOP,
|
||||
EXPR_OPERATOR_CHARS,
|
||||
EXPR_OPTIONAL,
|
||||
|
||||
@@ -97,16 +97,24 @@ bool expr_may_addr(Expr *expr)
|
||||
case EXPR_COND:
|
||||
case EXPR_CONST:
|
||||
case EXPR_DECL:
|
||||
case EXPR_DEFAULT_ARG:
|
||||
case EXPR_DESIGNATED_INITIALIZER_LIST:
|
||||
case EXPR_DESIGNATOR:
|
||||
case EXPR_EMBED:
|
||||
case EXPR_EXPRESSION_LIST:
|
||||
case EXPR_INITIALIZER_LIST:
|
||||
case EXPR_EXPR_BLOCK:
|
||||
case EXPR_OPTIONAL:
|
||||
case EXPR_FORCE_UNWRAP:
|
||||
case EXPR_GENERIC_IDENT:
|
||||
case EXPR_INITIALIZER_LIST:
|
||||
case EXPR_LAMBDA:
|
||||
case EXPR_LAST_FAULT:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_MACRO_BODY:
|
||||
case EXPR_MACRO_BODY_EXPANSION:
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
case EXPR_NOP:
|
||||
case EXPR_OPERATOR_CHARS:
|
||||
case EXPR_OPTIONAL:
|
||||
case EXPR_POINTER_OFFSET:
|
||||
case EXPR_POST_UNARY:
|
||||
case EXPR_RETHROW:
|
||||
@@ -115,20 +123,13 @@ bool expr_may_addr(Expr *expr)
|
||||
case EXPR_SLICE_COPY:
|
||||
case EXPR_SUBSCRIPT_ADDR:
|
||||
case EXPR_SUBSCRIPT_ASSIGN:
|
||||
case EXPR_SWIZZLE:
|
||||
case EXPR_TERNARY:
|
||||
case EXPR_TRY_UNWRAP:
|
||||
case EXPR_TRY_UNWRAP_CHAIN:
|
||||
case EXPR_TYPEID:
|
||||
case EXPR_TYPEID_INFO:
|
||||
case EXPR_VASPLAT:
|
||||
case EXPR_SWIZZLE:
|
||||
case EXPR_LAMBDA:
|
||||
case EXPR_GENERIC_IDENT:
|
||||
case EXPR_EMBED:
|
||||
case EXPR_MACRO_BODY:
|
||||
case EXPR_DEFAULT_ARG:
|
||||
case EXPR_LAST_FAULT:
|
||||
case EXPR_DESIGNATOR:
|
||||
return false;
|
||||
}
|
||||
UNREACHABLE
|
||||
@@ -340,6 +341,7 @@ bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind)
|
||||
case EXPR_SUBSCRIPT_ASSIGN:
|
||||
case EXPR_GENERIC_IDENT:
|
||||
case EXPR_MACRO_BODY:
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
UNREACHABLE
|
||||
case EXPR_NOP:
|
||||
return true;
|
||||
@@ -757,6 +759,7 @@ bool expr_is_pure(Expr *expr)
|
||||
case EXPR_RETHROW:
|
||||
case EXPR_HASH_IDENT:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
case EXPR_INITIALIZER_LIST:
|
||||
case EXPR_DESIGNATED_INITIALIZER_LIST:
|
||||
case EXPR_POST_UNARY:
|
||||
|
||||
@@ -7066,6 +7066,7 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
case EXPR_OTHER_CONTEXT:
|
||||
case EXPR_DESIGNATOR:
|
||||
case EXPR_MEMBER_GET:
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
UNREACHABLE
|
||||
case EXPR_DEFAULT_ARG:
|
||||
llvm_emit_default_arg(c, value, expr);
|
||||
|
||||
@@ -493,6 +493,79 @@ bool parse_arg_list(ParseContext *c, Expr ***result, TokenType param_end, bool *
|
||||
Expr *expr = NULL;
|
||||
DesignatorElement **path;
|
||||
SourceSpan start_span = c->span;
|
||||
|
||||
if (peek(c) == TOKEN_COLON && token_is_param_name(c->tok))
|
||||
{
|
||||
// Create the parameter expr
|
||||
expr = expr_new(EXPR_NAMED_ARGUMENT, start_span);
|
||||
expr->named_argument_expr.name = symstr(c);
|
||||
expr->named_argument_expr.name_span = c->span;
|
||||
advance(c);
|
||||
advance(c);
|
||||
ASSIGN_EXPR_OR_RET(expr->named_argument_expr.value, parse_expr(c), false);
|
||||
RANGE_EXTEND_PREV(expr);
|
||||
goto DONE;
|
||||
}
|
||||
if (tok_is(c, TOKEN_DOT) && token_is_param_name(peek(c)))
|
||||
{
|
||||
// Create the parameter expr
|
||||
expr = expr_new(EXPR_NAMED_ARGUMENT, start_span);
|
||||
advance(c);
|
||||
expr->named_argument_expr.name = symstr(c);
|
||||
expr->named_argument_expr.name_span = c->span;
|
||||
advance(c);
|
||||
CONSUME_OR_RET(TOKEN_EQ, false);
|
||||
ASSIGN_EXPR_OR_RET(expr->named_argument_expr.value, parse_expr(c), false);
|
||||
RANGE_EXTEND_PREV(expr);
|
||||
if (!compiler.context.silence_deprecation)
|
||||
{
|
||||
SEMA_NOTE(expr, "Named arguments using the '.foo = expr' style are deprecated, please use 'foo: expr' instead.");
|
||||
}
|
||||
goto DONE;
|
||||
}
|
||||
if (vasplat && tok_is(c, TOKEN_CT_VASPLAT))
|
||||
{
|
||||
ASSIGN_EXPR_OR_RET(expr, parse_vasplat(c), false);
|
||||
goto DONE;
|
||||
}
|
||||
if (splat)
|
||||
{
|
||||
if (*splat)
|
||||
{
|
||||
PRINT_ERROR_HERE("'...' is only allowed on the last argument in a call.");
|
||||
return false;
|
||||
}
|
||||
*splat = try_consume(c, TOKEN_ELLIPSIS);
|
||||
}
|
||||
ASSIGN_EXPR_OR_RET(expr, parse_expr(c), false);
|
||||
DONE:
|
||||
vec_add(*result, expr);
|
||||
if (!try_consume(c, TOKEN_COMMA))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (tok_is(c, param_end)) return true;
|
||||
if (splat && *splat)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* param_list ::= ('...' arg | arg (',' arg)*)?
|
||||
*
|
||||
* parameter ::= ((param_path '=')? expr) | param_path
|
||||
*/
|
||||
bool parse_init_list(ParseContext *c, Expr ***result, TokenType param_end, bool *splat, bool vasplat)
|
||||
{
|
||||
*result = NULL;
|
||||
if (splat) *splat = false;
|
||||
while (1)
|
||||
{
|
||||
Expr *expr = NULL;
|
||||
DesignatorElement **path;
|
||||
SourceSpan start_span = c->span;
|
||||
|
||||
if (!parse_param_path(c, &path)) return false;
|
||||
if (path != NULL)
|
||||
{
|
||||
@@ -500,29 +573,29 @@ bool parse_arg_list(ParseContext *c, Expr ***result, TokenType param_end, bool *
|
||||
expr = expr_new(EXPR_DESIGNATOR, start_span);
|
||||
expr->designator_expr.path = path;
|
||||
|
||||
if (try_consume(c, TOKEN_EQ)) {
|
||||
if (try_consume(c, TOKEN_EQ))
|
||||
{
|
||||
ASSIGN_EXPR_OR_RET(expr->designator_expr.value, parse_expr(c), false);
|
||||
}
|
||||
|
||||
RANGE_EXTEND_PREV(expr);
|
||||
goto DONE;
|
||||
}
|
||||
else if (vasplat && tok_is(c, TOKEN_CT_VASPLAT))
|
||||
if (vasplat && tok_is(c, TOKEN_CT_VASPLAT))
|
||||
{
|
||||
ASSIGN_EXPR_OR_RET(expr, parse_vasplat(c), false);
|
||||
goto DONE;
|
||||
}
|
||||
else
|
||||
if (splat)
|
||||
{
|
||||
if (splat)
|
||||
if (*splat)
|
||||
{
|
||||
if (*splat)
|
||||
{
|
||||
PRINT_ERROR_HERE("'...' is only allowed on the last argument in a call.");
|
||||
return false;
|
||||
}
|
||||
*splat = try_consume(c, TOKEN_ELLIPSIS);
|
||||
PRINT_ERROR_HERE("'...' is only allowed on the last argument in a call.");
|
||||
return false;
|
||||
}
|
||||
ASSIGN_EXPR_OR_RET(expr, parse_expr(c), false);
|
||||
*splat = try_consume(c, TOKEN_ELLIPSIS);
|
||||
}
|
||||
ASSIGN_EXPR_OR_RET(expr, parse_expr(c), false);
|
||||
DONE:
|
||||
vec_add(*result, expr);
|
||||
if (!try_consume(c, TOKEN_COMMA))
|
||||
{
|
||||
@@ -809,7 +882,7 @@ Expr *parse_initializer_list(ParseContext *c, Expr *left)
|
||||
if (!try_consume(c, TOKEN_RBRACE))
|
||||
{
|
||||
Expr **exprs = NULL;
|
||||
if (!parse_arg_list(c, &exprs, TOKEN_RBRACE, NULL, true)) return poisoned_expr;
|
||||
if (!parse_init_list(c, &exprs, TOKEN_RBRACE, NULL, true)) return poisoned_expr;
|
||||
int designated = -1;
|
||||
FOREACH(Expr *, expr, exprs)
|
||||
{
|
||||
|
||||
@@ -113,6 +113,19 @@ INLINE bool expect(ParseContext *c, TokenType token_type)
|
||||
return false;
|
||||
}
|
||||
|
||||
INLINE bool token_is_param_name(TokenType token_type)
|
||||
{
|
||||
switch (token_type)
|
||||
{
|
||||
case TOKEN_CT_IDENT:
|
||||
case TOKEN_IDENT:
|
||||
case TOKEN_HASH_IDENT:
|
||||
case TOKEN_CT_TYPE_IDENT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
INLINE bool token_is_some_ident(TokenType token_type)
|
||||
{
|
||||
switch (token_type)
|
||||
|
||||
@@ -137,7 +137,6 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
|
||||
Expr **args, unsigned func_param_count,
|
||||
Variadic variadic, unsigned vararg_index, bool *optional,
|
||||
Expr ***varargs_ref, Expr **vararg_splat_ref, bool *no_match_ref);
|
||||
static inline int sema_call_find_index_of_named_parameter(SemaContext *context, Decl **func_params, Expr *expr);
|
||||
static inline bool sema_call_check_contract_param_match(SemaContext *context, Decl *param, Expr *expr);
|
||||
static bool sema_call_analyse_body_expansion(SemaContext *macro_context, Expr *call);
|
||||
static bool sema_slice_len_is_in_range(SemaContext *context, Type *type, Expr *len_expr, bool from_end, bool *remove_from_end);
|
||||
@@ -594,6 +593,7 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp
|
||||
case EXPR_MACRO_BODY:
|
||||
case EXPR_LAST_FAULT:
|
||||
case EXPR_MEMBER_GET:
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
goto ERR;
|
||||
}
|
||||
UNREACHABLE
|
||||
@@ -668,8 +668,9 @@ static bool expr_may_ref(Expr *expr)
|
||||
case EXPR_EXPRESSION_LIST:
|
||||
if (!vec_size(expr->expression_list)) return false;
|
||||
return expr_may_ref(VECLAST(expr->expression_list));
|
||||
case EXPR_POISONED:
|
||||
case EXPR_ANYSWITCH:
|
||||
case EXPR_ASM:
|
||||
case EXPR_BENCHMARK_HOOK:
|
||||
case EXPR_BINARY:
|
||||
case EXPR_BITASSIGN:
|
||||
case EXPR_BUILTIN:
|
||||
@@ -681,27 +682,32 @@ static bool expr_may_ref(Expr *expr)
|
||||
case EXPR_COMPOUND_LITERAL:
|
||||
case EXPR_COND:
|
||||
case EXPR_CONST:
|
||||
case EXPR_CT_ARG:
|
||||
case EXPR_CT_CASTABLE:
|
||||
case EXPR_CT_AND_OR:
|
||||
case EXPR_CT_APPEND:
|
||||
case EXPR_CT_ARG:
|
||||
case EXPR_CT_CALL:
|
||||
case EXPR_CT_CASTABLE:
|
||||
case EXPR_CT_CONCAT:
|
||||
case EXPR_CT_DEFINED:
|
||||
case EXPR_CT_IS_CONST:
|
||||
case EXPR_CT_APPEND:
|
||||
case EXPR_CT_EVAL:
|
||||
case EXPR_CT_IS_CONST:
|
||||
case EXPR_DECL:
|
||||
case EXPR_DESIGNATED_INITIALIZER_LIST:
|
||||
case EXPR_DESIGNATOR:
|
||||
case EXPR_EXPR_BLOCK:
|
||||
case EXPR_OPTIONAL:
|
||||
case EXPR_FORCE_UNWRAP:
|
||||
case EXPR_GENERIC_IDENT:
|
||||
case EXPR_INITIALIZER_LIST:
|
||||
case EXPR_LAST_FAULT:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_MACRO_BODY:
|
||||
case EXPR_MACRO_BODY_EXPANSION:
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
case EXPR_NOP:
|
||||
case EXPR_OPERATOR_CHARS:
|
||||
case EXPR_OPTIONAL:
|
||||
case EXPR_POINTER_OFFSET:
|
||||
case EXPR_POISONED:
|
||||
case EXPR_POST_UNARY:
|
||||
case EXPR_RETHROW:
|
||||
case EXPR_RETVAL:
|
||||
@@ -709,18 +715,13 @@ static bool expr_may_ref(Expr *expr)
|
||||
case EXPR_SLICE_COPY:
|
||||
case EXPR_STRINGIFY:
|
||||
case EXPR_TERNARY:
|
||||
case EXPR_TEST_HOOK:
|
||||
case EXPR_TRY_UNWRAP:
|
||||
case EXPR_TRY_UNWRAP_CHAIN:
|
||||
case EXPR_TYPEID:
|
||||
case EXPR_TYPEID_INFO:
|
||||
case EXPR_TYPEINFO:
|
||||
case EXPR_ANYSWITCH:
|
||||
case EXPR_VASPLAT:
|
||||
case EXPR_BENCHMARK_HOOK:
|
||||
case EXPR_TEST_HOOK:
|
||||
case EXPR_GENERIC_IDENT:
|
||||
case EXPR_MACRO_BODY:
|
||||
case EXPR_LAST_FAULT:
|
||||
return false;
|
||||
}
|
||||
UNREACHABLE
|
||||
@@ -1185,51 +1186,17 @@ static inline bool sema_binary_analyse_arithmetic_subexpr(SemaContext *context,
|
||||
return sema_binary_arithmetic_promotion(context, left, right, left_type, right_type, expr, error, bool_and_bitstruct_is_allowed);
|
||||
}
|
||||
|
||||
|
||||
static inline int sema_call_find_index_of_named_parameter(SemaContext *context, Decl **func_params, Expr *expr)
|
||||
{
|
||||
if (vec_size(expr->designator_expr.path) != 1)
|
||||
{
|
||||
SEMA_ERROR(expr, "Expected the name of a function parameter here, this looks like a member path.");
|
||||
return -1;
|
||||
}
|
||||
DesignatorElement *element = expr->designator_expr.path[0];
|
||||
if (element->kind != DESIGNATOR_FIELD)
|
||||
{
|
||||
SEMA_ERROR(expr, "Expected the name of a function parameter here, this looks like an array path field.");
|
||||
return -1;
|
||||
}
|
||||
Expr *field = sema_expr_resolve_access_child(context, element->field_expr, NULL);
|
||||
if (!field) return false;
|
||||
|
||||
const char *name;
|
||||
switch (field->expr_kind)
|
||||
{
|
||||
case EXPR_IDENTIFIER:
|
||||
name = field->identifier_expr.ident;
|
||||
break;
|
||||
case EXPR_CT_IDENT:
|
||||
name = field->ct_ident_expr.identifier;
|
||||
break;
|
||||
case EXPR_TYPEINFO:
|
||||
name = field->type_expr->unresolved.name;
|
||||
break;
|
||||
default:
|
||||
SEMA_ERROR(expr, "A name was expected here.");
|
||||
return -1;
|
||||
}
|
||||
const char *name = expr->named_argument_expr.name;
|
||||
FOREACH_IDX(i, Decl *, func_param, func_params)
|
||||
{
|
||||
if (func_param && func_param->name == name) return (int) i;
|
||||
if (func_param && func_param->name == name) return (int)i;
|
||||
}
|
||||
SEMA_ERROR(expr, "There's no parameter with the name '%s'.", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static inline bool sema_call_check_invalid_body_arguments(SemaContext *context, Expr *call, CalledDecl *callee)
|
||||
{
|
||||
Expr *macro_body = exprptrzero(call->call_expr.macro_body);
|
||||
@@ -1301,13 +1268,14 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
|
||||
// 2. Loop through the parameters.
|
||||
bool has_named = false;
|
||||
bool found_splat = false;
|
||||
ArrayIndex last_index = -1;
|
||||
Expr *last_named_arg;
|
||||
for (unsigned i = 0; i < num_args; i++)
|
||||
{
|
||||
Expr *arg = args[i];
|
||||
assert(expr_ok(arg));
|
||||
|
||||
// 3. Handle named parameters
|
||||
if (arg->expr_kind == EXPR_DESIGNATOR)
|
||||
if (arg->expr_kind == EXPR_NAMED_ARGUMENT)
|
||||
{
|
||||
// Find the location of the parameter.
|
||||
int index = sema_call_find_index_of_named_parameter(context, params, arg);
|
||||
@@ -1323,7 +1291,7 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
|
||||
if (params[index]->var.vararg)
|
||||
{
|
||||
RETURN_SEMA_FUNC_ERROR(callee->definition, arg, "Vararg parameters may not be named parameters, "
|
||||
"use normal parameters instead.", params[index]->name);
|
||||
"use normal parameters instead.", params[index]->name);
|
||||
}
|
||||
|
||||
// 8e. We might have already set this parameter, that is not allowed.
|
||||
@@ -1332,12 +1300,16 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
|
||||
RETURN_SEMA_ERROR(arg, "The parameter '%s' was already set.", params[index]->name);
|
||||
}
|
||||
|
||||
// 8g. Set the parameter
|
||||
if (!arg->designator_expr.value)
|
||||
if (last_index > index)
|
||||
{
|
||||
RETURN_SEMA_ERROR(arg, "Expected a value for this argument.");
|
||||
|
||||
SEMA_ERROR(arg, "Named arguments must always be declared in order.");
|
||||
SEMA_NOTE(last_named_arg, "Place it before this argument.");
|
||||
return false;
|
||||
}
|
||||
actual_args[index] = arg->designator_expr.value;
|
||||
last_index = index;
|
||||
last_named_arg = arg;
|
||||
actual_args[index] = arg->named_argument_expr.value;
|
||||
continue;
|
||||
}
|
||||
if (*vararg_splat_ref)
|
||||
@@ -1467,7 +1439,7 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
|
||||
print_error_after(args[num_args - 1]->span, "Argument #%d is not set.", i);
|
||||
RETURN_NOTE_FUNC_DEFINITION;
|
||||
}
|
||||
print_error_after(args[num_args - 1]->span, "Expected '.%s = ...' after this argument.", param->name);
|
||||
print_error_after(args[num_args - 1]->span, "Expected '%s: ...' after this argument.", param->name);
|
||||
RETURN_NOTE_FUNC_DEFINITION;
|
||||
}
|
||||
if (num_args > (callee->struct_var ? 1 : 0))
|
||||
@@ -8966,6 +8938,7 @@ static inline bool sema_expr_analyse_ct_defined(SemaContext *context, Expr *expr
|
||||
case EXPR_DECL:
|
||||
case EXPR_LAST_FAULT:
|
||||
case EXPR_DEFAULT_ARG:
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
UNREACHABLE
|
||||
case EXPR_CT_ARG:
|
||||
FALLTHROUGH;
|
||||
@@ -9668,6 +9641,7 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr)
|
||||
case EXPR_MACRO_BODY:
|
||||
case EXPR_DEFAULT_ARG:
|
||||
case EXPR_MEMBER_GET:
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
UNREACHABLE
|
||||
case EXPR_TAGOF:
|
||||
RETURN_SEMA_ERROR(expr, "Expected '()' after this.");
|
||||
|
||||
@@ -262,6 +262,7 @@ RETRY:
|
||||
case EXPR_MACRO_BODY:
|
||||
case EXPR_OTHER_CONTEXT:
|
||||
case EXPR_MEMBER_GET:
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
UNREACHABLE
|
||||
case EXPR_DESIGNATOR:
|
||||
sema_trace_expr_liveness(expr->designator_expr.value);
|
||||
|
||||
@@ -623,6 +623,7 @@ static inline bool sema_expr_valid_try_expression(Expr *expr)
|
||||
case EXPR_CT_DEFINED:
|
||||
case EXPR_CT_EVAL:
|
||||
case EXPR_CT_IDENT:
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
UNREACHABLE
|
||||
case EXPR_BINARY:
|
||||
case EXPR_POINTER_OFFSET:
|
||||
|
||||
@@ -9,7 +9,7 @@ macro foo($bar, $Type)
|
||||
|
||||
fn void bar()
|
||||
{
|
||||
int x = foo(.$bar = 167, .$Type = int);
|
||||
int x = foo($bar: 167, $Type: int);
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
@@ -29,8 +29,8 @@ import std::io;
|
||||
fn void main()
|
||||
{
|
||||
test::test(1, 2);
|
||||
test::test(.a = 3);
|
||||
test::test(1, .b = 32);
|
||||
test::test(a: 3);
|
||||
test::test(1, b: 32);
|
||||
test::test();
|
||||
test::test();
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ fn void main()
|
||||
{
|
||||
Func a = &test;
|
||||
Func b = &test2;
|
||||
io::printfn("%d", a(.y = 123));
|
||||
io::printfn("%d", a(y: 123));
|
||||
io::printfn("%d", (&test2)());
|
||||
FuncSame z = &test2;
|
||||
io::printfn("%d", z());
|
||||
|
||||
11
test/test_suite/functions/named_arg_order.c3
Normal file
11
test/test_suite/functions/named_arg_order.c3
Normal file
@@ -0,0 +1,11 @@
|
||||
import std;
|
||||
macro void test(int a, int $baz)
|
||||
{
|
||||
io::printn(a + $baz);
|
||||
}
|
||||
|
||||
fn void main()
|
||||
{
|
||||
test(.$baz = 1, .a = 4); // #error: Named arguments must always
|
||||
test($baz: 1, a: 4); // #error: Named arguments must always
|
||||
}
|
||||
@@ -4,5 +4,5 @@ fn void test(int... abc, int a)
|
||||
fn void main()
|
||||
{
|
||||
int[] b = { 1, 2 };
|
||||
test(...b, .a = 123);
|
||||
test(...b, a: 123);
|
||||
}
|
||||
@@ -13,12 +13,12 @@ fn void test2(int x, int... y, int z)
|
||||
|
||||
fn void a()
|
||||
{
|
||||
test(.z = 32, 3); // #error: Named arguments must be placed after positional arguments
|
||||
test(z: 32, 3); // #error: Named arguments must be placed after positional arguments
|
||||
}
|
||||
|
||||
fn void b()
|
||||
{
|
||||
test(1, .x = 3); // #error: The parameter 'x' was already set.
|
||||
test(1, x: 3); // #error: The parameter 'x' was already set.
|
||||
}
|
||||
|
||||
fn void c()
|
||||
@@ -28,8 +28,8 @@ fn void c()
|
||||
|
||||
fn void d()
|
||||
{
|
||||
test2(1, .z = 3);
|
||||
test2(1, 2, 3); // #error: Expected '.z = ...' after this argument
|
||||
test2(1, z: 3);
|
||||
test2(1, 2, 3); // #error: Expected 'z: ...' after this argument
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ fn void test2(int x, y..., int z = 2)
|
||||
|
||||
fn void main()
|
||||
{
|
||||
test(3, 4, 5, .z = 123);
|
||||
test2(3, 4, 5, .z = 123);
|
||||
test(3, 4, 5, z: 123);
|
||||
test2(3, 4, 5, z: 123);
|
||||
test(3, 4, 5);
|
||||
test2(3, 4, 5);
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ fn void! main()
|
||||
|
||||
String foo_tmpl = "<<{{foo}} | {{bar}}>>";
|
||||
FooTmpl ft;
|
||||
ft.init(foo_tmpl, .using = allocator::temp())!;
|
||||
ft.init(foo_tmpl, using: allocator::temp())!;
|
||||
defer ft.free()!!;
|
||||
|
||||
|
||||
|
||||
@@ -492,7 +492,7 @@ struct TrieNode
|
||||
fn void Trie.init(&self, usz initial_capacity = 8, Allocator using = allocator::heap())
|
||||
{
|
||||
*self = {};
|
||||
self.nodes.new_init(initial_capacity, .allocator = using);
|
||||
self.nodes.new_init(initial_capacity, allocator: using);
|
||||
self.nodes.push(TrieNode{});
|
||||
}
|
||||
|
||||
|
||||
@@ -21,197 +21,197 @@ fn void! test_parent()
|
||||
{
|
||||
Path p = path::new("")!;
|
||||
assert(@catch(p.parent()));
|
||||
p = path::new("/", .path_env = PathEnv.POSIX)!;
|
||||
p = path::new("/", path_env: PathEnv.POSIX)!;
|
||||
assert(@catch(p.parent()));
|
||||
p = path::new("/a/b/c", .path_env = PathEnv.POSIX)!;
|
||||
p = path::new("/a/b/c", path_env: PathEnv.POSIX)!;
|
||||
assert(p.parent().str_view()! == "/a/b");
|
||||
p = path::new("/a/b/c", .path_env = PathEnv.WIN32)!;
|
||||
p = path::new("/a/b/c", path_env: PathEnv.WIN32)!;
|
||||
assert(p.parent().str_view()! == `\a\b`);
|
||||
}
|
||||
|
||||
fn void! test_path_normalized()
|
||||
{
|
||||
assert(path::new("", .path_env = PathEnv.WIN32).str_view()! == "");
|
||||
assert(@catch(path::new("1:\\a\\b\\c.txt", .path_env = PathEnv.WIN32)));
|
||||
assert(@catch(path::new(":", .path_env = PathEnv.WIN32)));
|
||||
assert(@catch(path::new("1:", .path_env = PathEnv.WIN32)));
|
||||
assert(@catch(path::new("1:a", .path_env = PathEnv.WIN32)));
|
||||
// assert(@catch(path::new(`\\\a\b\c.txt`, .path_env = PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`\\server\a\b\..\..\..\c`, .path_env = PathEnv.WIN32)));
|
||||
assert(path::new("", path_env: PathEnv.WIN32).str_view()! == "");
|
||||
assert(@catch(path::new("1:\\a\\b\\c.txt", path_env: PathEnv.WIN32)));
|
||||
assert(@catch(path::new(":", path_env: PathEnv.WIN32)));
|
||||
assert(@catch(path::new("1:", path_env: PathEnv.WIN32)));
|
||||
assert(@catch(path::new("1:a", path_env: PathEnv.WIN32)));
|
||||
// assert(@catch(path::new(`\\\a\b\c.txt`, path_env: PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`\\server\a\b\..\..\..\c`, path_env: PathEnv.WIN32)));
|
||||
|
||||
assert(@catch(path::new(`\\a`, .path_env = PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`/a/b/../../../c`, .path_env = PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`/a/b/../../../c`, .path_env = PathEnv.POSIX)));
|
||||
assert(@catch(path::new(`/a/b/../../..`, .path_env = PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`/a/b/../../..`, .path_env = PathEnv.POSIX)));
|
||||
assert(@catch(path::new(`/../a`, .path_env = PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`/../a`, .path_env = PathEnv.POSIX)));
|
||||
assert(@catch(path::new(`/..`, .path_env = PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`/..`, .path_env = PathEnv.POSIX)));
|
||||
assert(@catch(path::new(`C:/a/b/../../../c`, .path_env = PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`C:/../a`, .path_env = PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`C:/..`, .path_env = PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`\\a`, path_env: PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`/a/b/../../../c`, path_env: PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`/a/b/../../../c`, path_env: PathEnv.POSIX)));
|
||||
assert(@catch(path::new(`/a/b/../../..`, path_env: PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`/a/b/../../..`, path_env: PathEnv.POSIX)));
|
||||
assert(@catch(path::new(`/../a`, path_env: PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`/../a`, path_env: PathEnv.POSIX)));
|
||||
assert(@catch(path::new(`/..`, path_env: PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`/..`, path_env: PathEnv.POSIX)));
|
||||
assert(@catch(path::new(`C:/a/b/../../../c`, path_env: PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`C:/../a`, path_env: PathEnv.WIN32)));
|
||||
assert(@catch(path::new(`C:/..`, path_env: PathEnv.WIN32)));
|
||||
|
||||
assert(path::new("/", .path_env = PathEnv.POSIX).str_view()! == "/");
|
||||
assert(path::new("/./", .path_env = PathEnv.POSIX).str_view()! == "/");
|
||||
assert(path::new("/foo/../", .path_env = PathEnv.POSIX).str_view()! == "/");
|
||||
assert(path::new("/foo/bar/../", .path_env = PathEnv.POSIX).str_view()! == "/foo");
|
||||
assert(path::new("/foo//bar", .path_env = PathEnv.POSIX).str_view()! == "/foo/bar");
|
||||
assert(path::new("/foo//bar/../", .path_env = PathEnv.POSIX).str_view()! == "/foo");
|
||||
assert(path::new("/foo/.bar", .path_env = PathEnv.POSIX).str_view()! == "/foo/.bar");
|
||||
assert(path::new(`\foo\.bar`, .path_env = PathEnv.WIN32).str_view()! == `\foo\.bar`);
|
||||
assert(path::new("a\\b/c.txt", .path_env = PathEnv.WIN32).str_view()! == `a\b\c.txt`);
|
||||
assert(path::new("a\\b/c.txt", .path_env = PathEnv.POSIX).str_view()! == "a\\b/c.txt");
|
||||
assert(path::new("C:\\a\\b/c.txt", .path_env = PathEnv.WIN32).str_view()! == `C:\a\b\c.txt`);
|
||||
assert(path::new("C:\\a\\b/c.txt", .path_env = PathEnv.POSIX).str_view()! == "C:\\a\\b/c.txt");
|
||||
assert(path::new(`\\server\a\b/c.txt`, .path_env = PathEnv.WIN32).str_view()! == `\\server\a\b\c.txt`);
|
||||
assert(path::new(`\\server\a\b/c.txt`, .path_env = PathEnv.POSIX).str_view()! == `\\server\a\b/c.txt`);
|
||||
assert(path::new(`c:\hello//bar\\\\foo.txt`, .path_env = PathEnv.WIN32).str_view()! == `c:\hello\bar\foo.txt`);
|
||||
assert(path::new("/", path_env: PathEnv.POSIX).str_view()! == "/");
|
||||
assert(path::new("/./", path_env: PathEnv.POSIX).str_view()! == "/");
|
||||
assert(path::new("/foo/../", path_env: PathEnv.POSIX).str_view()! == "/");
|
||||
assert(path::new("/foo/bar/../", path_env: PathEnv.POSIX).str_view()! == "/foo");
|
||||
assert(path::new("/foo//bar", path_env: PathEnv.POSIX).str_view()! == "/foo/bar");
|
||||
assert(path::new("/foo//bar/../", path_env: PathEnv.POSIX).str_view()! == "/foo");
|
||||
assert(path::new("/foo/.bar", path_env: PathEnv.POSIX).str_view()! == "/foo/.bar");
|
||||
assert(path::new(`\foo\.bar`, path_env: PathEnv.WIN32).str_view()! == `\foo\.bar`);
|
||||
assert(path::new("a\\b/c.txt", path_env: PathEnv.WIN32).str_view()! == `a\b\c.txt`);
|
||||
assert(path::new("a\\b/c.txt", path_env: PathEnv.POSIX).str_view()! == "a\\b/c.txt");
|
||||
assert(path::new("C:\\a\\b/c.txt", path_env: PathEnv.WIN32).str_view()! == `C:\a\b\c.txt`);
|
||||
assert(path::new("C:\\a\\b/c.txt", path_env: PathEnv.POSIX).str_view()! == "C:\\a\\b/c.txt");
|
||||
assert(path::new(`\\server\a\b/c.txt`, path_env: PathEnv.WIN32).str_view()! == `\\server\a\b\c.txt`);
|
||||
assert(path::new(`\\server\a\b/c.txt`, path_env: PathEnv.POSIX).str_view()! == `\\server\a\b/c.txt`);
|
||||
assert(path::new(`c:\hello//bar\\\\foo.txt`, path_env: PathEnv.WIN32).str_view()! == `c:\hello\bar\foo.txt`);
|
||||
|
||||
assert(path::new(`~\a\b/c.txt`, .path_env = PathEnv.WIN32).str_view()! == `~\a\b\c.txt`);
|
||||
assert(path::new(`~\a\b/c.txt`, .path_env = PathEnv.POSIX).str_view()! == `~\a\b/c.txt`);
|
||||
assert(path::new(`~\a\b/c.txt`, path_env: PathEnv.WIN32).str_view()! == `~\a\b\c.txt`);
|
||||
assert(path::new(`~\a\b/c.txt`, path_env: PathEnv.POSIX).str_view()! == `~\a\b/c.txt`);
|
||||
|
||||
|
||||
assert(path::new(`a/b/../../../c`, .path_env = PathEnv.WIN32).str_view()! == `..\c`);
|
||||
assert(path::new(`a/b/../../../c`, .path_env = PathEnv.POSIX).str_view()! == `../c`);
|
||||
assert(path::new(`a/b/../../..`, .path_env = PathEnv.WIN32).str_view()! == `..`);
|
||||
assert(path::new(`a/b/../../..`, .path_env = PathEnv.POSIX).str_view()! == `..`);
|
||||
assert(path::new(`../a`, .path_env = PathEnv.WIN32).str_view()! == `..\a`);
|
||||
assert(path::new(`../a`, .path_env = PathEnv.POSIX).str_view()! == `../a`);
|
||||
assert(path::new(`..`, .path_env = PathEnv.WIN32).str_view()! == `..`);
|
||||
assert(path::new(`..`, .path_env = PathEnv.POSIX).str_view()! == `..`);
|
||||
assert(path::new(`a/b/../c`, .path_env = PathEnv.WIN32).str_view()! == `a\c`);
|
||||
assert(path::new(`a/b/../c`, .path_env = PathEnv.POSIX).str_view()! == `a/c`);
|
||||
assert(path::new(`a/b/../../c`, .path_env = PathEnv.WIN32).str_view()! == `c`);
|
||||
assert(path::new(`a/b/../../c`, .path_env = PathEnv.POSIX).str_view()! == `c`);
|
||||
assert(path::new(`a/b/..`, .path_env = PathEnv.WIN32).str_view()! == `a`);
|
||||
assert(path::new(`a/b/..`, .path_env = PathEnv.POSIX).str_view()! == `a`);
|
||||
assert(path::new(`a/b/../`, .path_env = PathEnv.WIN32).str_view()! == `a`);
|
||||
assert(path::new(`a/b/../`, .path_env = PathEnv.POSIX).str_view()! == `a`);
|
||||
assert(path::new(`a/b/../..`, .path_env = PathEnv.WIN32).str_view()! == ".");
|
||||
assert(path::new(`a/b/../..`, .path_env = PathEnv.POSIX).str_view()! == ".");
|
||||
assert(path::new(`a/b/../../`, .path_env = PathEnv.WIN32).str_view()! == ".");
|
||||
assert(path::new(`a/b/../../`, .path_env = PathEnv.POSIX).str_view()! == ".");
|
||||
assert(path::new(`a/b/../c/../d`, .path_env = PathEnv.WIN32).str_view()! == `a\d`);
|
||||
assert(path::new(`a/b/../c/../d`, .path_env = PathEnv.POSIX).str_view()! == `a/d`);
|
||||
assert(path::new(`a/b/../c/../d/`, .path_env = PathEnv.WIN32).str_view()! == `a\d`);
|
||||
assert(path::new(`a/b/../c/../d/`, .path_env = PathEnv.POSIX).str_view()! == `a/d`);
|
||||
assert(path::new(`a/b//d`, .path_env = PathEnv.WIN32).str_view()! == `a\b\d`);
|
||||
assert(path::new(`a/b//d`, .path_env = PathEnv.POSIX).str_view()! == `a/b/d`);
|
||||
assert(path::new(`a/b/././.`, .path_env = PathEnv.WIN32).str_view()! == `a\b`);
|
||||
assert(path::new(`a/b/././.`, .path_env = PathEnv.POSIX).str_view()! == `a/b`);
|
||||
assert(path::new(`a/b/./././`, .path_env = PathEnv.WIN32).str_view()! == `a\b`);
|
||||
assert(path::new(`a/b/./././`, .path_env = PathEnv.POSIX).str_view()! == `a/b`);
|
||||
assert(path::new(`./a/`, .path_env = PathEnv.WIN32).str_view()! == `a`);
|
||||
assert(path::new(`./a/`, .path_env = PathEnv.POSIX).str_view()! == `a`);
|
||||
assert(path::new(`./`, .path_env = PathEnv.WIN32).str_view()! == `.`);
|
||||
assert(path::new(`./`, .path_env = PathEnv.POSIX).str_view()! == `.`);
|
||||
assert(path::new(`.`, .path_env = PathEnv.WIN32).str_view()! == `.`);
|
||||
assert(path::new(`.`, .path_env = PathEnv.POSIX).str_view()! == `.`);
|
||||
assert(path::new(``, .path_env = PathEnv.WIN32).str_view()! == ``);
|
||||
assert(path::new(``, .path_env = PathEnv.POSIX).str_view()! == ``);
|
||||
assert(path::new(`/a`, .path_env = PathEnv.WIN32).str_view()! == `\a`);
|
||||
assert(path::new(`/a`, .path_env = PathEnv.POSIX).str_view()! == `/a`);
|
||||
assert(path::new(`/a/`, .path_env = PathEnv.WIN32).str_view()! == `\a`);
|
||||
assert(path::new(`/a/`, .path_env = PathEnv.POSIX).str_view()! == `/a`);
|
||||
assert(path::new(`/a/b/../c`, .path_env = PathEnv.WIN32).str_view()! == `\a\c`);
|
||||
assert(path::new(`/a/b/../c`, .path_env = PathEnv.POSIX).str_view()! == `/a/c`);
|
||||
assert(path::new(`/a/b/../../c`, .path_env = PathEnv.WIN32).str_view()! == `\c`);
|
||||
assert(path::new(`/a/b/../../c`, .path_env = PathEnv.POSIX).str_view()! == `/c`);
|
||||
assert(path::new(`/a/b/..`, .path_env = PathEnv.WIN32).str_view()! == `\a`);
|
||||
assert(path::new(`/a/b/..`, .path_env = PathEnv.POSIX).str_view()! == `/a`);
|
||||
assert(path::new(`/a/b/../..`, .path_env = PathEnv.WIN32).str_view()! == `\`);
|
||||
assert(path::new(`/a/b/../..`, .path_env = PathEnv.POSIX).str_view()! == `/`);
|
||||
assert(path::new(`/a/b/../c/../d`, .path_env = PathEnv.WIN32).str_view()! == `\a\d`);
|
||||
assert(path::new(`/a/b/../c/../d`, .path_env = PathEnv.POSIX).str_view()! == `/a/d`);
|
||||
assert(path::new(`/a/b//d`, .path_env = PathEnv.WIN32).str_view()! == `\a\b\d`);
|
||||
assert(path::new(`/a/b//d`, .path_env = PathEnv.POSIX).str_view()! == `/a/b/d`);
|
||||
assert(path::new(`/./a/`, .path_env = PathEnv.WIN32).str_view()! == `\a`);
|
||||
assert(path::new(`/./a/`, .path_env = PathEnv.POSIX).str_view()! == `/a`);
|
||||
assert(path::new(`/./`, .path_env = PathEnv.WIN32).str_view()! == `\`);
|
||||
assert(path::new(`/./`, .path_env = PathEnv.POSIX).str_view()! == `/`);
|
||||
assert(path::new(`/.`, .path_env = PathEnv.WIN32).str_view()! == `\`);
|
||||
assert(path::new(`/.`, .path_env = PathEnv.POSIX).str_view()! == `/`);
|
||||
assert(path::new(`/`, .path_env = PathEnv.WIN32).str_view()! == `\`);
|
||||
assert(path::new(`/`, .path_env = PathEnv.POSIX).str_view()! == `/`);
|
||||
assert(path::new(`C:/a`, .path_env = PathEnv.WIN32).str_view()! == `C:\a`);
|
||||
assert(path::new(`C:/a`, .path_env = PathEnv.POSIX).str_view()! == `C:/a`);
|
||||
assert(path::new(`C:/a/b/../c`, .path_env = PathEnv.WIN32).str_view()! == `C:\a\c`);
|
||||
assert(path::new(`C:/a/b/../c`, .path_env = PathEnv.POSIX).str_view()! == `C:/a/c`);
|
||||
assert(path::new(`C:/a/b/../../c`, .path_env = PathEnv.WIN32).str_view()! == `C:\c`);
|
||||
assert(path::new(`C:/a/b/../../c`, .path_env = PathEnv.POSIX).str_view()! == `C:/c`);
|
||||
assert(path::new(`C:/a/b/../../../c`, .path_env = PathEnv.POSIX).str_view()! == `c`);
|
||||
assert(path::new(`C:/a/b/..`, .path_env = PathEnv.WIN32).str_view()! == `C:\a`);
|
||||
assert(path::new(`C:/a/b/..`, .path_env = PathEnv.POSIX).str_view()! == `C:/a`);
|
||||
assert(path::new(`C:/a/b/../..`, .path_env = PathEnv.WIN32).str_view()! == `C:\`);
|
||||
assert(path::new(`C:/a/b/../..`, .path_env = PathEnv.POSIX).str_view()! == `C:`);
|
||||
assert(path::new(`C:/a/b/../c/../d`, .path_env = PathEnv.WIN32).str_view()! == `C:\a\d`);
|
||||
assert(path::new(`C:/a/b/../c/../d`, .path_env = PathEnv.POSIX).str_view()! == `C:/a/d`);
|
||||
assert(path::new(`C:/a/b//d`, .path_env = PathEnv.WIN32).str_view()! == `C:\a\b\d`);
|
||||
assert(path::new(`C:/a/b//d`, .path_env = PathEnv.POSIX).str_view()! == `C:/a/b/d`);
|
||||
assert(path::new(`C:/a/b/././.`, .path_env = PathEnv.WIN32).str_view()! == `C:\a\b`);
|
||||
assert(path::new(`C:/a/b/././.`, .path_env = PathEnv.POSIX).str_view()! == `C:/a/b`);
|
||||
assert(path::new(`C:/./a`, .path_env = PathEnv.WIN32).str_view()! == `C:\a`);
|
||||
assert(path::new(`C:/./a`, .path_env = PathEnv.POSIX).str_view()! == `C:/a`);
|
||||
assert(path::new(`C:/./`, .path_env = PathEnv.WIN32).str_view()! == `C:\`);
|
||||
assert(path::new(`C:/./`, .path_env = PathEnv.POSIX).str_view()! == `C:`);
|
||||
assert(path::new(`C:/../a`, .path_env = PathEnv.POSIX).str_view()! == `a`);
|
||||
assert(path::new(`C:/..`, .path_env = PathEnv.POSIX).str_view()! == `.`);
|
||||
assert(path::new(`C:/`, .path_env = PathEnv.WIN32).str_view()! == `C:\`);
|
||||
assert(path::new(`C:/`, .path_env = PathEnv.POSIX).str_view()! == `C:`);
|
||||
assert(path::new(`C:a`, .path_env = PathEnv.WIN32).str_view()! == `C:a`);
|
||||
assert(path::new(`C:a`, .path_env = PathEnv.POSIX).str_view()! == `C:a`);
|
||||
assert(path::new(`C:a/`, .path_env = PathEnv.WIN32).str_view()! == `C:a`);
|
||||
assert(path::new(`C:a/`, .path_env = PathEnv.POSIX).str_view()! == `C:a`);
|
||||
assert(path::new(`a/b/../../../c`, path_env: PathEnv.WIN32).str_view()! == `..\c`);
|
||||
assert(path::new(`a/b/../../../c`, path_env: PathEnv.POSIX).str_view()! == `../c`);
|
||||
assert(path::new(`a/b/../../..`, path_env: PathEnv.WIN32).str_view()! == `..`);
|
||||
assert(path::new(`a/b/../../..`, path_env: PathEnv.POSIX).str_view()! == `..`);
|
||||
assert(path::new(`../a`, path_env: PathEnv.WIN32).str_view()! == `..\a`);
|
||||
assert(path::new(`../a`, path_env: PathEnv.POSIX).str_view()! == `../a`);
|
||||
assert(path::new(`..`, path_env: PathEnv.WIN32).str_view()! == `..`);
|
||||
assert(path::new(`..`, path_env: PathEnv.POSIX).str_view()! == `..`);
|
||||
assert(path::new(`a/b/../c`, path_env: PathEnv.WIN32).str_view()! == `a\c`);
|
||||
assert(path::new(`a/b/../c`, path_env: PathEnv.POSIX).str_view()! == `a/c`);
|
||||
assert(path::new(`a/b/../../c`, path_env: PathEnv.WIN32).str_view()! == `c`);
|
||||
assert(path::new(`a/b/../../c`, path_env: PathEnv.POSIX).str_view()! == `c`);
|
||||
assert(path::new(`a/b/..`, path_env: PathEnv.WIN32).str_view()! == `a`);
|
||||
assert(path::new(`a/b/..`, path_env: PathEnv.POSIX).str_view()! == `a`);
|
||||
assert(path::new(`a/b/../`, path_env: PathEnv.WIN32).str_view()! == `a`);
|
||||
assert(path::new(`a/b/../`, path_env: PathEnv.POSIX).str_view()! == `a`);
|
||||
assert(path::new(`a/b/../..`, path_env: PathEnv.WIN32).str_view()! == ".");
|
||||
assert(path::new(`a/b/../..`, path_env: PathEnv.POSIX).str_view()! == ".");
|
||||
assert(path::new(`a/b/../../`, path_env: PathEnv.WIN32).str_view()! == ".");
|
||||
assert(path::new(`a/b/../../`, path_env: PathEnv.POSIX).str_view()! == ".");
|
||||
assert(path::new(`a/b/../c/../d`, path_env: PathEnv.WIN32).str_view()! == `a\d`);
|
||||
assert(path::new(`a/b/../c/../d`, path_env: PathEnv.POSIX).str_view()! == `a/d`);
|
||||
assert(path::new(`a/b/../c/../d/`, path_env: PathEnv.WIN32).str_view()! == `a\d`);
|
||||
assert(path::new(`a/b/../c/../d/`, path_env: PathEnv.POSIX).str_view()! == `a/d`);
|
||||
assert(path::new(`a/b//d`, path_env: PathEnv.WIN32).str_view()! == `a\b\d`);
|
||||
assert(path::new(`a/b//d`, path_env: PathEnv.POSIX).str_view()! == `a/b/d`);
|
||||
assert(path::new(`a/b/././.`, path_env: PathEnv.WIN32).str_view()! == `a\b`);
|
||||
assert(path::new(`a/b/././.`, path_env: PathEnv.POSIX).str_view()! == `a/b`);
|
||||
assert(path::new(`a/b/./././`, path_env: PathEnv.WIN32).str_view()! == `a\b`);
|
||||
assert(path::new(`a/b/./././`, path_env: PathEnv.POSIX).str_view()! == `a/b`);
|
||||
assert(path::new(`./a/`, path_env: PathEnv.WIN32).str_view()! == `a`);
|
||||
assert(path::new(`./a/`, path_env: PathEnv.POSIX).str_view()! == `a`);
|
||||
assert(path::new(`./`, path_env: PathEnv.WIN32).str_view()! == `.`);
|
||||
assert(path::new(`./`, path_env: PathEnv.POSIX).str_view()! == `.`);
|
||||
assert(path::new(`.`, path_env: PathEnv.WIN32).str_view()! == `.`);
|
||||
assert(path::new(`.`, path_env: PathEnv.POSIX).str_view()! == `.`);
|
||||
assert(path::new(``, path_env: PathEnv.WIN32).str_view()! == ``);
|
||||
assert(path::new(``, path_env: PathEnv.POSIX).str_view()! == ``);
|
||||
assert(path::new(`/a`, path_env: PathEnv.WIN32).str_view()! == `\a`);
|
||||
assert(path::new(`/a`, path_env: PathEnv.POSIX).str_view()! == `/a`);
|
||||
assert(path::new(`/a/`, path_env: PathEnv.WIN32).str_view()! == `\a`);
|
||||
assert(path::new(`/a/`, path_env: PathEnv.POSIX).str_view()! == `/a`);
|
||||
assert(path::new(`/a/b/../c`, path_env: PathEnv.WIN32).str_view()! == `\a\c`);
|
||||
assert(path::new(`/a/b/../c`, path_env: PathEnv.POSIX).str_view()! == `/a/c`);
|
||||
assert(path::new(`/a/b/../../c`, path_env: PathEnv.WIN32).str_view()! == `\c`);
|
||||
assert(path::new(`/a/b/../../c`, path_env: PathEnv.POSIX).str_view()! == `/c`);
|
||||
assert(path::new(`/a/b/..`, path_env: PathEnv.WIN32).str_view()! == `\a`);
|
||||
assert(path::new(`/a/b/..`, path_env: PathEnv.POSIX).str_view()! == `/a`);
|
||||
assert(path::new(`/a/b/../..`, path_env: PathEnv.WIN32).str_view()! == `\`);
|
||||
assert(path::new(`/a/b/../..`, path_env: PathEnv.POSIX).str_view()! == `/`);
|
||||
assert(path::new(`/a/b/../c/../d`, path_env: PathEnv.WIN32).str_view()! == `\a\d`);
|
||||
assert(path::new(`/a/b/../c/../d`, path_env: PathEnv.POSIX).str_view()! == `/a/d`);
|
||||
assert(path::new(`/a/b//d`, path_env: PathEnv.WIN32).str_view()! == `\a\b\d`);
|
||||
assert(path::new(`/a/b//d`, path_env: PathEnv.POSIX).str_view()! == `/a/b/d`);
|
||||
assert(path::new(`/./a/`, path_env: PathEnv.WIN32).str_view()! == `\a`);
|
||||
assert(path::new(`/./a/`, path_env: PathEnv.POSIX).str_view()! == `/a`);
|
||||
assert(path::new(`/./`, path_env: PathEnv.WIN32).str_view()! == `\`);
|
||||
assert(path::new(`/./`, path_env: PathEnv.POSIX).str_view()! == `/`);
|
||||
assert(path::new(`/.`, path_env: PathEnv.WIN32).str_view()! == `\`);
|
||||
assert(path::new(`/.`, path_env: PathEnv.POSIX).str_view()! == `/`);
|
||||
assert(path::new(`/`, path_env: PathEnv.WIN32).str_view()! == `\`);
|
||||
assert(path::new(`/`, path_env: PathEnv.POSIX).str_view()! == `/`);
|
||||
assert(path::new(`C:/a`, path_env: PathEnv.WIN32).str_view()! == `C:\a`);
|
||||
assert(path::new(`C:/a`, path_env: PathEnv.POSIX).str_view()! == `C:/a`);
|
||||
assert(path::new(`C:/a/b/../c`, path_env: PathEnv.WIN32).str_view()! == `C:\a\c`);
|
||||
assert(path::new(`C:/a/b/../c`, path_env: PathEnv.POSIX).str_view()! == `C:/a/c`);
|
||||
assert(path::new(`C:/a/b/../../c`, path_env: PathEnv.WIN32).str_view()! == `C:\c`);
|
||||
assert(path::new(`C:/a/b/../../c`, path_env: PathEnv.POSIX).str_view()! == `C:/c`);
|
||||
assert(path::new(`C:/a/b/../../../c`, path_env: PathEnv.POSIX).str_view()! == `c`);
|
||||
assert(path::new(`C:/a/b/..`, path_env: PathEnv.WIN32).str_view()! == `C:\a`);
|
||||
assert(path::new(`C:/a/b/..`, path_env: PathEnv.POSIX).str_view()! == `C:/a`);
|
||||
assert(path::new(`C:/a/b/../..`, path_env: PathEnv.WIN32).str_view()! == `C:\`);
|
||||
assert(path::new(`C:/a/b/../..`, path_env: PathEnv.POSIX).str_view()! == `C:`);
|
||||
assert(path::new(`C:/a/b/../c/../d`, path_env: PathEnv.WIN32).str_view()! == `C:\a\d`);
|
||||
assert(path::new(`C:/a/b/../c/../d`, path_env: PathEnv.POSIX).str_view()! == `C:/a/d`);
|
||||
assert(path::new(`C:/a/b//d`, path_env: PathEnv.WIN32).str_view()! == `C:\a\b\d`);
|
||||
assert(path::new(`C:/a/b//d`, path_env: PathEnv.POSIX).str_view()! == `C:/a/b/d`);
|
||||
assert(path::new(`C:/a/b/././.`, path_env: PathEnv.WIN32).str_view()! == `C:\a\b`);
|
||||
assert(path::new(`C:/a/b/././.`, path_env: PathEnv.POSIX).str_view()! == `C:/a/b`);
|
||||
assert(path::new(`C:/./a`, path_env: PathEnv.WIN32).str_view()! == `C:\a`);
|
||||
assert(path::new(`C:/./a`, path_env: PathEnv.POSIX).str_view()! == `C:/a`);
|
||||
assert(path::new(`C:/./`, path_env: PathEnv.WIN32).str_view()! == `C:\`);
|
||||
assert(path::new(`C:/./`, path_env: PathEnv.POSIX).str_view()! == `C:`);
|
||||
assert(path::new(`C:/../a`, path_env: PathEnv.POSIX).str_view()! == `a`);
|
||||
assert(path::new(`C:/..`, path_env: PathEnv.POSIX).str_view()! == `.`);
|
||||
assert(path::new(`C:/`, path_env: PathEnv.WIN32).str_view()! == `C:\`);
|
||||
assert(path::new(`C:/`, path_env: PathEnv.POSIX).str_view()! == `C:`);
|
||||
assert(path::new(`C:a`, path_env: PathEnv.WIN32).str_view()! == `C:a`);
|
||||
assert(path::new(`C:a`, path_env: PathEnv.POSIX).str_view()! == `C:a`);
|
||||
assert(path::new(`C:a/`, path_env: PathEnv.WIN32).str_view()! == `C:a`);
|
||||
assert(path::new(`C:a/`, path_env: PathEnv.POSIX).str_view()! == `C:a`);
|
||||
|
||||
assert(path::new(`C:a/b/../c`, .path_env = PathEnv.WIN32).str_view()! == `C:a\c`);
|
||||
assert(path::new(`C:a/b/../c`, .path_env = PathEnv.POSIX).str_view()! == `C:a/c`);
|
||||
assert(path::new(`C:a/b/../../c`, .path_env = PathEnv.WIN32).str_view()! == `C:c`);
|
||||
assert(path::new(`C:a/b/../../c`, .path_env = PathEnv.POSIX).str_view()! == `c`);
|
||||
assert(path::new(`C:a/b/..`, .path_env = PathEnv.WIN32).str_view()! == `C:a`);
|
||||
assert(path::new(`C:a/b/..`, .path_env = PathEnv.POSIX).str_view()! == `C:a`);
|
||||
assert(path::new(`C:a/b/../..`, .path_env = PathEnv.WIN32).str_view()! == `C:`);
|
||||
assert(path::new(`C:a/b/../..`, .path_env = PathEnv.POSIX).str_view()! == `.`);
|
||||
assert(path::new(`C:a/b/../c/../d`, .path_env = PathEnv.WIN32).str_view()! == `C:a\d`);
|
||||
assert(path::new(`C:a/b/../c/../d`, .path_env = PathEnv.POSIX).str_view()! == `C:a/d`);
|
||||
assert(path::new(`C:a/b//d`, .path_env = PathEnv.WIN32).str_view()! == `C:a\b\d`);
|
||||
assert(path::new(`C:a/b//d`, .path_env = PathEnv.POSIX).str_view()! == `C:a/b/d`);
|
||||
assert(path::new(`C:a/b/././.`, .path_env = PathEnv.WIN32).str_view()! == `C:a\b`);
|
||||
assert(path::new(`C:a/b/././.`, .path_env = PathEnv.POSIX).str_view()! == `C:a/b`);
|
||||
assert(path::new(`C:a/b/../../../c`, .path_env = PathEnv.WIN32).str_view()! == `C:..\c`);
|
||||
assert(path::new(`C:./a`, .path_env = PathEnv.WIN32).str_view()! == `C:a`);
|
||||
assert(path::new(`C:./a`, .path_env = PathEnv.POSIX).str_view()! == `C:./a`);
|
||||
assert(path::new(`C:./`, .path_env = PathEnv.WIN32).str_view()! == `C:`);
|
||||
assert(path::new(`C:./`, .path_env = PathEnv.POSIX).str_view()! == `C:.`);
|
||||
assert(path::new(`C:../a`, .path_env = PathEnv.POSIX).str_view()! == `C:../a`);
|
||||
assert(path::new(`C:../a`, .path_env = PathEnv.WIN32).str_view()! == `C:..\a`);
|
||||
assert(path::new(`C:..`, .path_env = PathEnv.POSIX).str_view()! == `C:..`);
|
||||
assert(path::new(`C:..`, .path_env = PathEnv.WIN32).str_view()! == `C:..`);
|
||||
assert(path::new(`C:`, .path_env = PathEnv.WIN32).str_view()! == `C:`);
|
||||
assert(path::new(`C:`, .path_env = PathEnv.POSIX).str_view()! == `C:`);
|
||||
assert(path::new(`C:a/b/../c`, path_env: PathEnv.WIN32).str_view()! == `C:a\c`);
|
||||
assert(path::new(`C:a/b/../c`, path_env: PathEnv.POSIX).str_view()! == `C:a/c`);
|
||||
assert(path::new(`C:a/b/../../c`, path_env: PathEnv.WIN32).str_view()! == `C:c`);
|
||||
assert(path::new(`C:a/b/../../c`, path_env: PathEnv.POSIX).str_view()! == `c`);
|
||||
assert(path::new(`C:a/b/..`, path_env: PathEnv.WIN32).str_view()! == `C:a`);
|
||||
assert(path::new(`C:a/b/..`, path_env: PathEnv.POSIX).str_view()! == `C:a`);
|
||||
assert(path::new(`C:a/b/../..`, path_env: PathEnv.WIN32).str_view()! == `C:`);
|
||||
assert(path::new(`C:a/b/../..`, path_env: PathEnv.POSIX).str_view()! == `.`);
|
||||
assert(path::new(`C:a/b/../c/../d`, path_env: PathEnv.WIN32).str_view()! == `C:a\d`);
|
||||
assert(path::new(`C:a/b/../c/../d`, path_env: PathEnv.POSIX).str_view()! == `C:a/d`);
|
||||
assert(path::new(`C:a/b//d`, path_env: PathEnv.WIN32).str_view()! == `C:a\b\d`);
|
||||
assert(path::new(`C:a/b//d`, path_env: PathEnv.POSIX).str_view()! == `C:a/b/d`);
|
||||
assert(path::new(`C:a/b/././.`, path_env: PathEnv.WIN32).str_view()! == `C:a\b`);
|
||||
assert(path::new(`C:a/b/././.`, path_env: PathEnv.POSIX).str_view()! == `C:a/b`);
|
||||
assert(path::new(`C:a/b/../../../c`, path_env: PathEnv.WIN32).str_view()! == `C:..\c`);
|
||||
assert(path::new(`C:./a`, path_env: PathEnv.WIN32).str_view()! == `C:a`);
|
||||
assert(path::new(`C:./a`, path_env: PathEnv.POSIX).str_view()! == `C:./a`);
|
||||
assert(path::new(`C:./`, path_env: PathEnv.WIN32).str_view()! == `C:`);
|
||||
assert(path::new(`C:./`, path_env: PathEnv.POSIX).str_view()! == `C:.`);
|
||||
assert(path::new(`C:../a`, path_env: PathEnv.POSIX).str_view()! == `C:../a`);
|
||||
assert(path::new(`C:../a`, path_env: PathEnv.WIN32).str_view()! == `C:..\a`);
|
||||
assert(path::new(`C:..`, path_env: PathEnv.POSIX).str_view()! == `C:..`);
|
||||
assert(path::new(`C:..`, path_env: PathEnv.WIN32).str_view()! == `C:..`);
|
||||
assert(path::new(`C:`, path_env: PathEnv.WIN32).str_view()! == `C:`);
|
||||
assert(path::new(`C:`, path_env: PathEnv.POSIX).str_view()! == `C:`);
|
||||
|
||||
assert(path::new(`\\server\foo/a`, .path_env = PathEnv.WIN32).str_view()! == `\\server\foo\a`);
|
||||
assert(path::new(`\\server\foo/a`, .path_env = PathEnv.POSIX).str_view()! == `\\server\foo/a`);
|
||||
assert(path::new(`\\server\foo\a\b\..\c`, .path_env = PathEnv.WIN32).str_view()! == `\\server\foo\a\c`);
|
||||
assert(path::new(`\\server\foo\a\b\..\..\c`, .path_env = PathEnv.WIN32).str_view()! == `\\server\foo\c`);
|
||||
assert(path::new(`\\server\foo\a\b\..`, .path_env = PathEnv.WIN32).str_view()! == `\\server\foo\a`);
|
||||
assert(path::new(`\\server\foo\a\..`, .path_env = PathEnv.WIN32).str_view()! == `\\server\foo\`);
|
||||
assert(path::new(`\\server\foo\a\b\..\c\..\d`, .path_env = PathEnv.WIN32).str_view()! == `\\server\foo\a\d`);
|
||||
assert(path::new(`\\server\foo\a\b\\d`, .path_env = PathEnv.WIN32).str_view()! == `\\server\foo\a\b\d`);
|
||||
assert(path::new(`\\server\foo\a\b\.\.\.`, .path_env = PathEnv.WIN32).str_view()! == `\\server\foo\a\b`);
|
||||
assert(path::new(`\\server\foo\.\a`, .path_env = PathEnv.WIN32).str_view()! == `\\server\foo\a`);
|
||||
assert(path::new(`\\server\foo\.`, .path_env = PathEnv.WIN32).str_view()! == `\\server\foo\`);
|
||||
assert(path::new(`\\server\foo\`, .path_env = PathEnv.WIN32).str_view()! == `\\server\foo\`);
|
||||
assert(path::new(`\\server\foo/a`, path_env: PathEnv.WIN32).str_view()! == `\\server\foo\a`);
|
||||
assert(path::new(`\\server\foo/a`, path_env: PathEnv.POSIX).str_view()! == `\\server\foo/a`);
|
||||
assert(path::new(`\\server\foo\a\b\..\c`, path_env: PathEnv.WIN32).str_view()! == `\\server\foo\a\c`);
|
||||
assert(path::new(`\\server\foo\a\b\..\..\c`, path_env: PathEnv.WIN32).str_view()! == `\\server\foo\c`);
|
||||
assert(path::new(`\\server\foo\a\b\..`, path_env: PathEnv.WIN32).str_view()! == `\\server\foo\a`);
|
||||
assert(path::new(`\\server\foo\a\..`, path_env: PathEnv.WIN32).str_view()! == `\\server\foo\`);
|
||||
assert(path::new(`\\server\foo\a\b\..\c\..\d`, path_env: PathEnv.WIN32).str_view()! == `\\server\foo\a\d`);
|
||||
assert(path::new(`\\server\foo\a\b\\d`, path_env: PathEnv.WIN32).str_view()! == `\\server\foo\a\b\d`);
|
||||
assert(path::new(`\\server\foo\a\b\.\.\.`, path_env: PathEnv.WIN32).str_view()! == `\\server\foo\a\b`);
|
||||
assert(path::new(`\\server\foo\.\a`, path_env: PathEnv.WIN32).str_view()! == `\\server\foo\a`);
|
||||
assert(path::new(`\\server\foo\.`, path_env: PathEnv.WIN32).str_view()! == `\\server\foo\`);
|
||||
assert(path::new(`\\server\foo\`, path_env: PathEnv.WIN32).str_view()! == `\\server\foo\`);
|
||||
|
||||
}
|
||||
|
||||
fn void! test_extension()
|
||||
{
|
||||
assert(@catch(path::new(`C:`, .path_env = PathEnv.WIN32).extension()));
|
||||
assert(@catch(path::new(`C:`, .path_env = PathEnv.POSIX).extension()));
|
||||
assert(@catch(path::new(`file`, .path_env = PathEnv.WIN32).extension()));
|
||||
assert(@catch(path::new(`file`, .path_env = PathEnv.POSIX).extension()));
|
||||
assert(@catch(path::new(`C:\temp\foo.bar\README`, .path_env = PathEnv.WIN32).extension()));
|
||||
assert(@catch(path::new(`C:`, path_env: PathEnv.WIN32).extension()));
|
||||
assert(@catch(path::new(`C:`, path_env: PathEnv.POSIX).extension()));
|
||||
assert(@catch(path::new(`file`, path_env: PathEnv.WIN32).extension()));
|
||||
assert(@catch(path::new(`file`, path_env: PathEnv.POSIX).extension()));
|
||||
assert(@catch(path::new(`C:\temp\foo.bar\README`, path_env: PathEnv.WIN32).extension()));
|
||||
|
||||
assert(path::new_windows("file.txt").extension()! == "txt");
|
||||
assert(path::new_posix("file.txt").extension()! == "txt");
|
||||
@@ -241,7 +241,7 @@ fn void! test_extension()
|
||||
|
||||
fn void! test_has_extension()
|
||||
{
|
||||
assert(!path::new(`C:\temp\foo.bar\README`, .path_env = PathEnv.WIN32)!.has_extension(`bar\README`));
|
||||
assert(!path::new(`C:\temp\foo.bar\README`, path_env: PathEnv.WIN32)!.has_extension(`bar\README`));
|
||||
|
||||
assert(path::new_windows("file.txt")!.has_extension("txt"));
|
||||
assert(path::new_posix("file.txt")!.has_extension("txt"));
|
||||
|
||||
@@ -11,7 +11,7 @@ fn String add(String s, Allocator a, int x)
|
||||
};
|
||||
ulong* y = mem::temp_alloc(ulong);
|
||||
*y = 0xAAAA_AAAA_AAAA_AAAA;
|
||||
return tmp.concat("a", .allocator = a);
|
||||
return tmp.concat("a", allocator: a);
|
||||
}
|
||||
|
||||
fn String breakit(String s, Allocator a)
|
||||
|
||||
Reference in New Issue
Block a user