Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2916280
utils.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
8 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
;
}
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
,
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
,
&
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
)
{
OXC_free_stripped_output
(
stripped
,
stripped_len
);
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
);
OXC_free_stripped_output
(
stripped
,
stripped_len
);
*
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
*
dot
=
strrchr
(
filename
,
'.'
);
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
*
dot
=
strrchr
(
filename
,
'.'
);
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
;
}
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
;
#define RT_APPEND(c, data, dlen) do { \
if (*(c)->buf_len + (dlen) >= *(c)->buf_cap) { \
*(c)->buf_cap = (*(c)->buf_len + (dlen) + 1) * 2; \
*(c)->buf = realloc(*(c)->buf, *(c)->buf_cap); \
} \
memcpy(*(c)->buf + *(c)->buf_len, data, dlen); *(c)->buf_len += (dlen); \
} while(0)
static
void
rt_dollar
(
rt_ctx_t
*
c
)
{
RT_APPEND
(
c
,
"$"
,
1
);
*
c
->
ri
+=
2
;
}
static
void
rt_match
(
rt_ctx_t
*
c
)
{
RT_APPEND
(
c
,
c
->
matched
,
c
->
matched_len
);
*
c
->
ri
+=
2
;
}
static
void
rt_prefix
(
rt_ctx_t
*
c
)
{
RT_APPEND
(
c
,
c
->
str
,
c
->
position
);
*
c
->
ri
+=
2
;
}
static
void
rt_suffix
(
rt_ctx_t
*
c
)
{
size_t
after
=
c
->
position
+
c
->
matched_len
;
if
(
after
<
c
->
str_len
)
RT_APPEND
(
c
,
c
->
str
+
after
,
c
->
str_len
-
after
);
*
c
->
ri
+=
2
;
}
static
void
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
)
{
RT_APPEND
(
c
,
c
->
caps
[
gn
-
1
].
ptr
,
c
->
caps
[
gn
-
1
].
len
);
}
else
if
(
gn
==
0
||
gn
>
c
->
ncaptures
)
{
RT_APPEND
(
c
,
"$"
,
1
);
RT_APPEND
(
c
,
&
nc
,
1
);
}
}
typedef
void
(
*
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
;
}
void
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
)
{
h
(
&
c
);
continue
;
}
}
RT_APPEND
(
&
c
,
&
repl
[
ri
],
1
);
ri
++
;
}
}
#undef RT_APPEND
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
Thu, Mar 26, 4:46 PM (2 d)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
511725
Default Alt Text
utils.c (8 KB)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment