Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F4396117
utils.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
utils.c
View Options
#include
"utils.h"
#include
"messages.h"
#include
<oxc.h>
#include
<stdio.h>
#include
<stdbool.h>
#include
<sys/stat.h>
#include
<crprintf.h>
const
char
*
const
module_resolve_extensions
[]
=
{
".js"
,
".mjs"
,
".cjs"
,
".ts"
,
".mts"
,
".cts"
,
".json"
,
".node"
,
NULL
};
int
hex_digit
(
char
c
)
{
static
const
int8_t
lookup
[
256
]
=
{
[
'0'
]
=
0
,
[
'1'
]
=
1
,
[
'2'
]
=
2
,
[
'3'
]
=
3
,
[
'4'
]
=
4
,
[
'5'
]
=
5
,
[
'6'
]
=
6
,
[
'7'
]
=
7
,
[
'8'
]
=
8
,
[
'9'
]
=
9
,
[
'a'
]
=
10
,
[
'b'
]
=
11
,
[
'c'
]
=
12
,
[
'd'
]
=
13
,
[
'e'
]
=
14
,
[
'f'
]
=
15
,
[
'A'
]
=
10
,
[
'B'
]
=
11
,
[
'C'
]
=
12
,
[
'D'
]
=
13
,
[
'E'
]
=
14
,
[
'F'
]
=
15
,
};
int8_t
val
=
lookup
[(
unsigned
char
)
c
];
return
val
?
val
:
(
c
==
'0'
?
0
:
-1
);
}
char
hex_char
(
int
v
)
{
return
"0123456789abcdef"
[
v
&
0x0f
];
}
uint64_t
hash_key
(
const
char
*
key
,
size_t
len
)
{
uint64_t
hash
=
14695981039346656037ULL
;
size_t
i
=
0
;
for
(;
i
+
8
<=
len
;
i
+=
8
)
{
uint64_t
word
;
memcpy
(
&
word
,
key
+
i
,
8
);
hash
^=
word
;
hash
*=
1099511628211ULL
;
}
for
(;
i
<
len
;
i
++
)
{
hash
^=
(
uint8_t
)
key
[
i
];
hash
*=
1099511628211ULL
;
}
return
hash
;
}
double
half_to_double
(
uint16_t
bits16
)
{
uint32_t
sign
=
((
uint32_t
)
bits16
&
0x8000u
)
<<
16
;
uint32_t
exp
=
((
uint32_t
)
bits16
>>
10
)
&
0x1fu
;
uint32_t
mant
=
(
uint32_t
)
bits16
&
0x03ffu
;
uint32_t
bits32
=
0
;
float
out
=
0.0f
;
if
(
exp
==
0
)
{
if
(
mant
==
0
)
{
bits32
=
sign
;
}
else
{
uint32_t
exp32
=
113
;
while
((
mant
&
0x0400u
)
==
0
)
{
mant
<<=
1
;
exp32
--
;
}
mant
&=
0x03ffu
;
bits32
=
sign
|
(
exp32
<<
23
)
|
(
mant
<<
13
);
}}
else
if
(
exp
==
0x1fu
)
bits32
=
sign
|
0x7f800000u
|
(
mant
<<
13
);
else
bits32
=
sign
|
((
exp
+
112u
)
<<
23
)
|
(
mant
<<
13
);
memcpy
(
&
out
,
&
bits32
,
sizeof
(
out
));
return
(
double
)
out
;
}
uint16_t
double_to_half
(
double
value
)
{
float
input
=
(
float
)
value
;
uint32_t
bits32
=
0
;
uint32_t
sign
=
0
;
uint32_t
exp
=
0
;
uint32_t
mant
=
0
;
int32_t
exp16
=
0
;
uint16_t
out
=
0
;
memcpy
(
&
bits32
,
&
input
,
sizeof
(
bits32
));
sign
=
(
bits32
>>
16
)
&
0x8000u
;
exp
=
(
bits32
>>
23
)
&
0xffu
;
mant
=
bits32
&
0x007fffffu
;
if
(
exp
==
0xffu
)
{
if
(
mant
!=
0
)
return
(
uint16_t
)(
sign
|
0x7e00u
);
return
(
uint16_t
)(
sign
|
0x7c00u
);
}
exp16
=
(
int32_t
)
exp
-
127
+
15
;
if
(
exp16
>=
0x1f
)
return
(
uint16_t
)(
sign
|
0x7c00u
);
if
(
exp16
<=
0
)
{
if
(
exp16
<
-10
)
return
(
uint16_t
)
sign
;
mant
|=
0x00800000u
;
uint32_t
shift
=
(
uint32_t
)(
14
-
exp16
);
uint16_t
sub
=
(
uint16_t
)(
mant
>>
shift
);
if
((
mant
>>
(
shift
-
1
))
&
1u
)
sub
++
;
return
(
uint16_t
)(
sign
|
sub
);
}
out
=
(
uint16_t
)(
sign
|
((
uint32_t
)
exp16
<<
10
)
|
(
mant
>>
13
));
if
(
mant
&
0x00001000u
)
out
++
;
return
out
;
}
int
is_typescript_file
(
const
char
*
filename
)
{
if
(
filename
==
NULL
)
return
0
;
size_t
len
=
strlen
(
filename
);
if
(
len
<
3
)
return
0
;
const
char
*
ext
=
filename
+
len
;
while
(
ext
>
filename
&&
*
(
ext
-
1
)
!=
'.'
&&
*
(
ext
-
1
)
!=
'/'
)
ext
--
;
if
(
ext
==
filename
||
*
(
ext
-
1
)
!=
'.'
)
return
0
;
ext
--
;
return
(
strcmp
(
ext
,
".ts"
)
==
0
||
strcmp
(
ext
,
".mts"
)
==
0
||
strcmp
(
ext
,
".cts"
)
==
0
);
}
int
strip_typescript_inplace
(
char
**
buffer
,
size_t
len
,
const
char
*
filename
,
int
is_module
,
size_t
*
out_len
,
const
char
**
error_detail
)
{
if
(
out_len
)
*
out_len
=
len
;
if
(
error_detail
)
*
error_detail
=
NULL
;
if
(
!
is_typescript_file
(
filename
))
return
0
;
if
(
!
buffer
||
!*
buffer
)
{
if
(
error_detail
)
*
error_detail
=
"null input/output passed"
;
return
OXC_ERR_NULL_INPUT
;
}
char
*
input
=
*
buffer
;
char
error_buf
[
256
]
=
{
0
};
size_t
stripped_len
=
0
;
int
strip_error
=
OXC_ERR_TRANSFORM_FAILED
;
char
*
stripped
=
OXC_strip_types_owned
(
input
,
filename
,
is_module
,
&
stripped_len
,
&
strip_error
,
error_buf
,
sizeof
(
error_buf
)
);
if
(
!
stripped
)
{
if
(
error_buf
[
0
]
!=
'\0'
)
{
size_t
msg_len
=
strlen
(
error_buf
);
size_t
copy_len
=
msg_len
>
len
?
len
:
msg_len
;
memcpy
(
input
,
error_buf
,
copy_len
);
input
[
copy_len
]
=
'\0'
;
}
else
input
[
0
]
=
'\0'
;
if
(
error_detail
)
{
*
error_detail
=
input
[
0
]
!=
'\0'
?
input
:
"unknown strip error"
;
}
return
strip_error
;
}
char
*
next
=
realloc
(
input
,
stripped_len
+
1
);
if
(
!
next
)
{
free
(
stripped
);
if
(
error_detail
)
*
error_detail
=
"out of memory while resizing strip output buffer"
;
return
OXC_ERR_OUTPUT_TOO_LARGE
;
}
memcpy
(
next
,
stripped
,
stripped_len
+
1
);
free
(
stripped
);
*
buffer
=
next
;
if
(
out_len
)
*
out_len
=
stripped_len
;
return
0
;
}
static
bool
is_entrypoint_script_extension
(
const
char
*
ext
)
{
return
ext
&&
strcmp
(
ext
,
".json"
)
!=
0
&&
strcmp
(
ext
,
".node"
)
!=
0
;
}
static
bool
has_js_extension
(
const
char
*
filename
)
{
const
char
*
slash
=
strrchr
(
filename
,
'/'
);
const
char
*
base
=
slash
?
slash
+
1
:
filename
;
const
char
*
dot
=
strrchr
(
base
,
'.'
);
if
(
!
dot
)
return
false
;
for
(
const
char
*
const
*
ext
=
module_resolve_extensions
;
*
ext
;
ext
++
)
{
if
(
!
is_entrypoint_script_extension
(
*
ext
))
continue
;
if
(
strcmp
(
dot
,
*
ext
)
==
0
)
return
true
;
}
return
false
;
}
char
*
resolve_js_file
(
const
char
*
filename
)
{
extern
bool
esm_is_url
(
const
char
*
path
);
if
(
!
filename
)
return
NULL
;
if
(
esm_is_url
(
filename
))
return
strdup
(
filename
);
struct
stat
st
;
if
(
stat
(
filename
,
&
st
)
==
0
)
{
if
(
S_ISREG
(
st
.
st_mode
))
{
const
char
*
slash
=
strrchr
(
filename
,
'/'
);
const
char
*
base
=
slash
?
slash
+
1
:
filename
;
const
char
*
dot
=
strrchr
(
base
,
'.'
);
if
(
dot
&&
!
has_js_extension
(
filename
))
return
NULL
;
return
strdup
(
filename
);
}
if
(
!
S_ISDIR
(
st
.
st_mode
))
return
NULL
;
size_t
len
=
strlen
(
filename
);
int
has_slash
=
(
len
>
0
&&
filename
[
len
-
1
]
==
'/'
);
for
(
const
char
*
const
*
ext
=
module_resolve_extensions
;
*
ext
;
ext
++
)
{
if
(
!
is_entrypoint_script_extension
(
*
ext
))
continue
;
size_t
ext_len
=
strlen
(
*
ext
);
char
*
index_path
=
try_oom
(
len
+
7
+
ext_len
+
1
);
sprintf
(
index_path
,
"%s%sindex%s"
,
filename
,
has_slash
?
""
:
"/"
,
*
ext
);
if
(
stat
(
index_path
,
&
st
)
==
0
&&
S_ISREG
(
st
.
st_mode
))
return
index_path
;
free
(
index_path
);
}
return
NULL
;
}
if
(
has_js_extension
(
filename
))
return
NULL
;
size_t
base_len
=
strlen
(
filename
);
for
(
const
char
*
const
*
ext
=
module_resolve_extensions
;
*
ext
;
ext
++
)
{
if
(
!
is_entrypoint_script_extension
(
*
ext
))
continue
;
size_t
ext_len
=
strlen
(
*
ext
);
char
*
test_path
=
try_oom
(
base_len
+
ext_len
+
1
);
memcpy
(
test_path
,
filename
,
base_len
);
memcpy
(
test_path
+
base_len
,
*
ext
,
ext_len
+
1
);
if
(
stat
(
test_path
,
&
st
)
==
0
&&
S_ISREG
(
st
.
st_mode
))
{
return
test_path
;
}
free
(
test_path
);
}
return
NULL
;
}
char
*
resolve_typescript_source_fallback
(
const
char
*
filename
)
{
if
(
!
filename
)
return
NULL
;
const
char
*
mapped_ext
=
NULL
;
size_t
trim_len
=
0
;
size_t
len
=
strlen
(
filename
);
if
(
len
>
3
&&
strcmp
(
filename
+
len
-
3
,
".js"
)
==
0
)
{
mapped_ext
=
".ts"
;
trim_len
=
3
;
}
else
if
(
len
>
4
&&
strcmp
(
filename
+
len
-
4
,
".mjs"
)
==
0
)
{
mapped_ext
=
".mts"
;
trim_len
=
4
;
}
else
if
(
len
>
4
&&
strcmp
(
filename
+
len
-
4
,
".cjs"
)
==
0
)
{
mapped_ext
=
".cts"
;
trim_len
=
4
;
}
else
return
NULL
;
size_t
mapped_len
=
strlen
(
mapped_ext
);
char
*
mapped
=
try_oom
(
len
-
trim_len
+
mapped_len
+
1
);
memcpy
(
mapped
,
filename
,
len
-
trim_len
);
memcpy
(
mapped
+
len
-
trim_len
,
mapped_ext
,
mapped_len
+
1
);
return
mapped
;
}
typedef
struct
{
const
char
*
repl
;
size_t
repl_len
;
size_t
*
ri
;
const
char
*
matched
;
size_t
matched_len
;
const
char
*
str
;
size_t
str_len
;
size_t
position
;
const
repl_capture_t
*
caps
;
int
ncaptures
;
char
**
buf
;
size_t
*
buf_len
;
size_t
*
buf_cap
;
}
rt_ctx_t
;
static
bool
rt_append
(
rt_ctx_t
*
c
,
const
char
*
data
,
size_t
dlen
)
{
if
(
dlen
==
0
)
return
true
;
if
(
*
c
->
buf_len
>
SIZE_MAX
-
dlen
-
1
)
return
false
;
if
(
*
c
->
buf_len
+
dlen
>=
*
c
->
buf_cap
)
{
size_t
needed
=
*
c
->
buf_len
+
dlen
+
1
;
size_t
new_cap
=
needed
*
2
;
if
(
new_cap
<
needed
)
new_cap
=
needed
;
char
*
next
=
realloc
(
*
c
->
buf
,
new_cap
);
if
(
!
next
)
return
false
;
*
c
->
buf
=
next
;
*
c
->
buf_cap
=
new_cap
;
}
memcpy
(
*
c
->
buf
+
*
c
->
buf_len
,
data
,
dlen
);
*
c
->
buf_len
+=
dlen
;
return
true
;
}
static
bool
rt_dollar
(
rt_ctx_t
*
c
)
{
*
c
->
ri
+=
2
;
return
rt_append
(
c
,
"$"
,
1
);
}
static
bool
rt_match
(
rt_ctx_t
*
c
)
{
*
c
->
ri
+=
2
;
return
rt_append
(
c
,
c
->
matched
,
c
->
matched_len
);
}
static
bool
rt_prefix
(
rt_ctx_t
*
c
)
{
*
c
->
ri
+=
2
;
return
rt_append
(
c
,
c
->
str
,
c
->
position
);
}
static
bool
rt_suffix
(
rt_ctx_t
*
c
)
{
size_t
after
=
c
->
position
+
c
->
matched_len
;
bool
ok
=
true
;
if
(
after
<
c
->
str_len
)
ok
=
rt_append
(
c
,
c
->
str
+
after
,
c
->
str_len
-
after
);
*
c
->
ri
+=
2
;
return
ok
;
}
static
bool
rt_capture
(
rt_ctx_t
*
c
)
{
char
nc
=
c
->
repl
[
*
c
->
ri
+
1
];
int
gn
=
nc
-
'0'
;
*
c
->
ri
+=
2
;
if
(
*
c
->
ri
<
c
->
repl_len
&&
c
->
repl
[
*
c
->
ri
]
>=
'0'
&&
c
->
repl
[
*
c
->
ri
]
<=
'9'
)
{
int
two
=
gn
*
10
+
(
c
->
repl
[
*
c
->
ri
]
-
'0'
);
if
(
two
<=
c
->
ncaptures
)
{
gn
=
two
;
(
*
c
->
ri
)
++
;
}
}
if
(
gn
>
0
&&
gn
<=
c
->
ncaptures
&&
c
->
caps
[
gn
-
1
].
ptr
)
return
rt_append
(
c
,
c
->
caps
[
gn
-
1
].
ptr
,
c
->
caps
[
gn
-
1
].
len
);
if
(
gn
==
0
||
gn
>
c
->
ncaptures
)
return
rt_append
(
c
,
"$"
,
1
)
&&
rt_append
(
c
,
&
nc
,
1
);
return
true
;
}
typedef
bool
(
*
rt_handler_t
)(
rt_ctx_t
*
);
static
rt_handler_t
rt_dispatch
[
128
];
static
bool
rt_dispatch_init
=
false
;
static
void
rt_init_dispatch
(
void
)
{
if
(
rt_dispatch_init
)
return
;
rt_dispatch
[
'$'
]
=
rt_dollar
;
rt_dispatch
[
'&'
]
=
rt_match
;
rt_dispatch
[
'`'
]
=
rt_prefix
;
rt_dispatch
[
'\''
]
=
rt_suffix
;
for
(
int
i
=
'0'
;
i
<=
'9'
;
i
++
)
rt_dispatch
[
i
]
=
rt_capture
;
rt_dispatch_init
=
true
;
}
bool
repl_template
(
const
char
*
repl
,
size_t
repl_len
,
const
char
*
matched
,
size_t
matched_len
,
const
char
*
str
,
size_t
str_len
,
size_t
position
,
const
repl_capture_t
*
caps
,
int
ncaptures
,
char
**
buf
,
size_t
*
buf_len
,
size_t
*
buf_cap
)
{
rt_init_dispatch
();
rt_ctx_t
c
=
{
repl
,
repl_len
,
NULL
,
matched
,
matched_len
,
str
,
str_len
,
position
,
caps
,
ncaptures
,
buf
,
buf_len
,
buf_cap
,
};
for
(
size_t
ri
=
0
;
ri
<
repl_len
;
)
{
if
(
repl
[
ri
]
==
'$'
&&
ri
+
1
<
repl_len
)
{
unsigned
char
nc
=
(
unsigned
char
)
repl
[
ri
+
1
];
c
.
ri
=
&
ri
;
rt_handler_t
h
=
nc
<
128
?
rt_dispatch
[
nc
]
:
NULL
;
if
(
h
)
{
if
(
!
h
(
&
c
))
return
false
;
continue
;
}
}
if
(
!
rt_append
(
&
c
,
&
repl
[
ri
],
1
))
return
false
;
ri
++
;
}
return
true
;
}
void
*
try_oom
(
size_t
size
)
{
void
*
p
=
malloc
(
size
);
if
(
!
p
)
{
crfprintf
(
stderr
,
msg
.
oom_fatal
);
exit
(
EXIT_FAILURE
);
}
return
p
;
}
void
cstr_free
(
cstr_buf_t
*
buf
)
{
if
(
buf
->
heap
)
free
(
buf
->
heap
);
}
char
*
cstr_init
(
cstr_buf_t
*
buf
,
char
*
stack
,
size_t
stack_size
,
const
char
*
src
,
size_t
len
)
{
if
(
len
<
stack_size
)
{
buf
->
ptr
=
stack
;
buf
->
heap
=
NULL
;
}
else
{
buf
->
heap
=
malloc
(
len
+
1
);
if
(
!
buf
->
heap
)
return
NULL
;
buf
->
ptr
=
buf
->
heap
;
}
memcpy
(
buf
->
ptr
,
src
,
len
);
buf
->
ptr
[
len
]
=
'\0'
;
return
buf
->
ptr
;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Fri, May 1, 1:33 PM (1 d, 20 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
541367
Default Alt Text
utils.c (10 KB)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment