Skip to content

Commit

Permalink
Make errno behavior less magical
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli committed Dec 6, 2023
1 parent e8255f0 commit 8a9fd39
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 19 deletions.
6 changes: 0 additions & 6 deletions stdlib/_macos_startup.jou
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,3 @@ def _jou_macos_startup() -> void:
stdin = __stdinp
stdout = __stdoutp
stderr = __stderrp

# On linux, C's errno is a macro that expands to (*__errno_location()).
# On macos it expands to (*__error()) instead. Let's make it consistent.
declare __error() -> int*
def __errno_location() -> int*:
return __error()
6 changes: 0 additions & 6 deletions stdlib/_windows_startup.jou
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,3 @@ def _jou_windows_startup() -> void:
stdin = __acrt_iob_func(0)
stdout = __acrt_iob_func(1)
stderr = __acrt_iob_func(2)

# On linux, C's errno is a macro that expands to (*__errno_location()).
# On Windows it expands to (*_errno()) instead. Let's make it consistent.
declare _errno() -> int*
def __errno_location() -> int*:
return _errno()
36 changes: 29 additions & 7 deletions stdlib/errno.jou
Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@
# C's errno is actually a macro that expands to a function call.
# See also _windows_startup.jou
declare __errno_location() -> int*
# In C, you use errno as if it was a normal variable. It is actually a
# macro, meaning every "errno" in your code gets replaced with something
# else when compiling:
#
# - Windows: errno expands to (*_errno())
# - MacOS: errno expands to (*__error())
# - Linux: errno expands to (*__errno_location())
#
# Because Jou in general does not hide magic, we instead provide
# set_errno() and get_errno() functions.

def set_errno(value: int) -> void:
*__errno_location() = value
if WINDOWS:
declare _errno() -> int*
def set_errno(value: int) -> void:
*_errno() = value
def get_errno() -> int:
return *_errno()

def get_errno() -> int:
return *__errno_location()
elif MACOS:
declare __error() -> int*
def set_errno(value: int) -> void:
*__error() = value
def get_errno() -> int:
return *__error()

else:
declare __errno_location() -> int*
def set_errno(value: int) -> void:
*__errno_location() = value
def get_errno() -> int:
return *__errno_location()

# Convert an error code into a string. Do not modify or free() the returned string.
declare strerror(errno_value: int) -> byte*

0 comments on commit 8a9fd39

Please sign in to comment.