Convert sh to C.
This commit is contained in:
parent
8d58033846
commit
423285b855
18
sh/Makefile
18
sh/Makefile
|
@ -5,18 +5,18 @@ include ../build-aux/version.mak
|
||||||
include ../build-aux/dirs.mak
|
include ../build-aux/dirs.mak
|
||||||
|
|
||||||
OPTLEVEL?=$(DEFAULT_OPTLEVEL)
|
OPTLEVEL?=$(DEFAULT_OPTLEVEL)
|
||||||
CXXFLAGS?=$(OPTLEVEL)
|
CFLAGS?=$(OPTLEVEL)
|
||||||
|
|
||||||
CPPFLAGS:=$(CPPFLAGS) -DVERSIONSTR=\"$(VERSION)\"
|
CPPFLAGS:=$(CPPFLAGS) -DVERSIONSTR=\"$(VERSION)\"
|
||||||
CXXFLAGS:=$(CXXFLAGS) -Wall -Wextra -fno-exceptions -fno-rtti
|
CFLAGS:=$(CFLAGS) -Wall -Wextra
|
||||||
|
|
||||||
BINARIES:=sh sortix-sh
|
BINARIES:=sh sortix-sh
|
||||||
|
|
||||||
SORTIX_SH_SRCS=\
|
SORTIX_SH_SRCS=\
|
||||||
editline.cpp \
|
editline.c \
|
||||||
sh.cpp \
|
sh.c \
|
||||||
showline.cpp \
|
showline.c \
|
||||||
util.cpp
|
util.c
|
||||||
|
|
||||||
all: $(BINARIES)
|
all: $(BINARIES)
|
||||||
|
|
||||||
|
@ -27,10 +27,10 @@ install: all
|
||||||
install $(BINARIES) $(DESTDIR)$(BINDIR)
|
install $(BINARIES) $(DESTDIR)$(BINDIR)
|
||||||
|
|
||||||
sortix-sh: $(SORTIX_SH_SRCS) *.h
|
sortix-sh: $(SORTIX_SH_SRCS) *.h
|
||||||
$(CXX) -std=gnu++11 $(CPPFLAGS) $(CXXFLAGS) $(SORTIX_SH_SRCS) -o $@
|
$(CC) -std=gnu11 $(CFLAGS) $(CPPFLAGS) $(SORTIX_SH_SRCS) -o $@
|
||||||
|
|
||||||
sh: proper-sh.cpp
|
sh: proper-sh.c
|
||||||
$(CXX) -std=gnu++11 $(CPPFLAGS) $(CXXFLAGS) $< -o $@
|
$(CC) -std=gnu11 $(CFLAGS) $(CPPFLAGS) $< -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(BINARIES) *.o
|
rm -f $(BINARIES) *.o
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
You should have received a copy of the GNU General Public License along with
|
You should have received a copy of the GNU General Public License along with
|
||||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
editline.cpp
|
editline.c
|
||||||
Read a line from the terminal.
|
Read a line from the terminal.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -24,6 +24,7 @@
|
||||||
#include <sys/termmode.h>
|
#include <sys/termmode.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -596,7 +597,8 @@ void edit_line(struct edit_line* edit_state)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( int kbkey = KBKEY_DECODE(codepoint) )
|
int kbkey;
|
||||||
|
if ( (kbkey = KBKEY_DECODE(codepoint)) )
|
||||||
edit_line_kbkey(edit_state, kbkey);
|
edit_line_kbkey(edit_state, kbkey);
|
||||||
else
|
else
|
||||||
edit_line_codepoint(edit_state, (wchar_t) codepoint);
|
edit_line_codepoint(edit_state, (wchar_t) codepoint);
|
|
@ -15,7 +15,7 @@
|
||||||
You should have received a copy of the GNU General Public License along with
|
You should have received a copy of the GNU General Public License along with
|
||||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
proper-sh.cpp
|
proper-sh.c
|
||||||
Forward execution to the best shell.
|
Forward execution to the best shell.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -24,12 +24,13 @@
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
const char* getenv_safe(const char* name, const char* def = "")
|
const char* getenv_safe(const char* name, const char* def)
|
||||||
{
|
{
|
||||||
const char* ret = getenv(name);
|
const char* ret = getenv(name);
|
||||||
return ret ? ret : def;
|
return ret ? ret : def;
|
||||||
|
@ -56,7 +57,7 @@ bool is_existing_shell(const char* candidate)
|
||||||
return WIFEXITED(status) && WEXITSTATUS(status) == 0;
|
return WIFEXITED(status) && WEXITSTATUS(status) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* search_for_proper_shell()
|
char* search_for_proper_shell(void)
|
||||||
{
|
{
|
||||||
if ( getenv("SORTIX_SH_BACKEND") )
|
if ( getenv("SORTIX_SH_BACKEND") )
|
||||||
{
|
{
|
|
@ -15,7 +15,7 @@
|
||||||
You should have received a copy of the GNU General Public License along with
|
You should have received a copy of the GNU General Public License along with
|
||||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
sh.cpp
|
sh.c
|
||||||
Command language interpreter.
|
Command language interpreter.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -90,7 +91,7 @@ static bool is_proper_absolute_path(const char* path)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_env()
|
void update_env(void)
|
||||||
{
|
{
|
||||||
char str[3 * sizeof(size_t)];
|
char str[3 * sizeof(size_t)];
|
||||||
struct winsize ws;
|
struct winsize ws;
|
||||||
|
@ -349,7 +350,7 @@ bool token_expand_wildcards(void*** out,
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
size_t num_escaped_wildcards = 0; // We don't properly support them yet.
|
size_t num_escaped_wildcards = 0; // We don't properly support them yet.
|
||||||
|
|
||||||
stringbuf buf;
|
struct stringbuf buf;
|
||||||
stringbuf_begin(&buf);
|
stringbuf_begin(&buf);
|
||||||
|
|
||||||
bool escape = false;
|
bool escape = false;
|
||||||
|
@ -385,9 +386,10 @@ bool token_expand_wildcards(void*** out,
|
||||||
|
|
||||||
if ( token[index] != '*' || num_escaped_wildcards )
|
if ( token[index] != '*' || num_escaped_wildcards )
|
||||||
{
|
{
|
||||||
|
char* value;
|
||||||
free(stringbuf_finish(&buf));
|
free(stringbuf_finish(&buf));
|
||||||
just_return_input:
|
just_return_input:
|
||||||
char* value = strdup(token);
|
value = strdup(token);
|
||||||
if ( !value )
|
if ( !value )
|
||||||
return false;
|
return false;
|
||||||
if ( !array_add(out, out_used, out_length, value) )
|
if ( !array_add(out, out_used, out_length, value) )
|
||||||
|
@ -485,7 +487,8 @@ bool token_expand_wildcards(void*** out,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size_t num_inserted = 0;
|
size_t num_inserted = 0;
|
||||||
while ( struct dirent* entry = readdir(dir) )
|
struct dirent* entry;
|
||||||
|
while ( (entry = readdir(dir)) )
|
||||||
{
|
{
|
||||||
if ( !matches_simple_pattern(entry->d_name, pattern + match_from) )
|
if ( !matches_simple_pattern(entry->d_name, pattern + match_from) )
|
||||||
continue;
|
continue;
|
||||||
|
@ -867,7 +870,7 @@ struct execute_result
|
||||||
bool exited;
|
bool exited;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct execute_result execute(const char* const* tokens,
|
struct execute_result execute(char** tokens,
|
||||||
size_t tokens_count,
|
size_t tokens_count,
|
||||||
bool interactive,
|
bool interactive,
|
||||||
int pipein,
|
int pipein,
|
||||||
|
@ -1117,7 +1120,7 @@ struct execute_result execute(const char* const* tokens,
|
||||||
internal = true;
|
internal = true;
|
||||||
const char* newdir = argv[1];
|
const char* newdir = argv[1];
|
||||||
if ( !newdir )
|
if ( !newdir )
|
||||||
newdir = getenv_safe("HOME", "/");
|
newdir = getenv_safe_def("HOME", "/");
|
||||||
internal_status = 0;
|
internal_status = 0;
|
||||||
if ( perform_chdir(newdir) < 0 )
|
if ( perform_chdir(newdir) < 0 )
|
||||||
{
|
{
|
||||||
|
@ -1308,7 +1311,7 @@ struct execute_result execute(const char* const* tokens,
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
int run_tokens(const char* const* tokens,
|
int run_tokens(char** tokens,
|
||||||
size_t tokens_count,
|
size_t tokens_count,
|
||||||
bool interactive,
|
bool interactive,
|
||||||
bool exit_on_error,
|
bool exit_on_error,
|
||||||
|
@ -1542,12 +1545,13 @@ int run_command(char* command,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool does_line_editing_need_another_line(void*, const char* line)
|
bool does_line_editing_need_another_line(void* ctx, const char* line)
|
||||||
{
|
{
|
||||||
|
(void) ctx;
|
||||||
return !is_shell_input_ready(line);
|
return !is_shell_input_ready(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_outermost_shell()
|
bool is_outermost_shell(void)
|
||||||
{
|
{
|
||||||
const char* shlvl_str = getenv("SHLVL");
|
const char* shlvl_str = getenv("SHLVL");
|
||||||
if ( !shlvl_str )
|
if ( !shlvl_str )
|
||||||
|
@ -1576,10 +1580,12 @@ bool is_usual_char_for_completion(char c)
|
||||||
size_t do_complete(char*** completions_ptr,
|
size_t do_complete(char*** completions_ptr,
|
||||||
size_t* used_before_ptr,
|
size_t* used_before_ptr,
|
||||||
size_t* used_after_ptr,
|
size_t* used_after_ptr,
|
||||||
void*,
|
void* ctx,
|
||||||
const char* partial,
|
const char* partial,
|
||||||
size_t complete_at)
|
size_t complete_at)
|
||||||
{
|
{
|
||||||
|
(void) ctx;
|
||||||
|
|
||||||
size_t used_before = 0;
|
size_t used_before = 0;
|
||||||
size_t used_after = 0;
|
size_t used_after = 0;
|
||||||
|
|
||||||
|
@ -1658,9 +1664,11 @@ size_t do_complete(char*** completions_ptr,
|
||||||
char* component;
|
char* component;
|
||||||
while ( (component = strsep(&path_input, ":")) )
|
while ( (component = strsep(&path_input, ":")) )
|
||||||
{
|
{
|
||||||
if ( DIR* dir = opendir(component) )
|
DIR* dir;
|
||||||
|
if ( (dir = opendir(component)) )
|
||||||
{
|
{
|
||||||
while ( struct dirent* entry = readdir(dir) )
|
struct dirent* entry;
|
||||||
|
while ( (entry = readdir(dir)) )
|
||||||
{
|
{
|
||||||
if ( strncmp(entry->d_name, partial + complete_at - used_before, used_before) != 0 )
|
if ( strncmp(entry->d_name, partial + complete_at - used_before, used_before) != 0 )
|
||||||
continue;
|
continue;
|
||||||
|
@ -1716,7 +1724,8 @@ size_t do_complete(char*** completions_ptr,
|
||||||
free(dirpath_alloc);
|
free(dirpath_alloc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while ( struct dirent* entry = readdir(dir) )
|
struct dirent* entry;
|
||||||
|
while ( (entry = readdir(dir)) )
|
||||||
{
|
{
|
||||||
if ( strncmp(entry->d_name, pattern, pattern_length) != 0 )
|
if ( strncmp(entry->d_name, pattern, pattern_length) != 0 )
|
||||||
continue;
|
continue;
|
||||||
|
@ -1812,7 +1821,7 @@ void read_command_interactive(struct sh_read_command* sh_read_command)
|
||||||
strlcpy(hostname, "(none)", sizeof(hostname));
|
strlcpy(hostname, "(none)", sizeof(hostname));
|
||||||
const char* print_hostname = hostname;
|
const char* print_hostname = hostname;
|
||||||
const char* print_dir = current_dir ? current_dir : "?";
|
const char* print_dir = current_dir ? current_dir : "?";
|
||||||
const char* home_dir = getenv_safe("HOME", "");
|
const char* home_dir = getenv_safe("HOME");
|
||||||
|
|
||||||
const char* print_dir_1 = print_dir;
|
const char* print_dir_1 = print_dir;
|
||||||
const char* print_dir_2 = "";
|
const char* print_dir_2 = "";
|
||||||
|
@ -2064,7 +2073,8 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
// TODO: Canonicalize argv[0] if it contains a slash and isn't absolute?
|
// TODO: Canonicalize argv[0] if it contains a slash and isn't absolute?
|
||||||
|
|
||||||
if ( const char* env_pwd = getenv("PWD") )
|
const char* env_pwd;
|
||||||
|
if ( (env_pwd = getenv("PWD")) )
|
||||||
{
|
{
|
||||||
if ( !is_proper_absolute_path(env_pwd) )
|
if ( !is_proper_absolute_path(env_pwd) )
|
||||||
{
|
{
|
||||||
|
@ -2092,7 +2102,8 @@ int main(int argc, char* argv[])
|
||||||
break;
|
break;
|
||||||
if ( arg[0] == '+' )
|
if ( arg[0] == '+' )
|
||||||
{
|
{
|
||||||
while ( char c = *++arg ) switch ( c )
|
char c;
|
||||||
|
while ( (c = *++arg) ) switch ( c )
|
||||||
{
|
{
|
||||||
case 'e': flag_e_exit_on_error = false; break;
|
case 'e': flag_e_exit_on_error = false; break;
|
||||||
default:
|
default:
|
||||||
|
@ -2103,7 +2114,8 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
else if ( arg[1] != '-' )
|
else if ( arg[1] != '-' )
|
||||||
{
|
{
|
||||||
while ( char c = *++arg ) switch ( c )
|
char c;
|
||||||
|
while ( (c = *++arg) ) switch ( c )
|
||||||
{
|
{
|
||||||
case 'c': flag_c_first_operand_is_command = true; break;
|
case 'c': flag_c_first_operand_is_command = true; break;
|
||||||
case 'e': flag_e_exit_on_error = true; break;
|
case 'e': flag_e_exit_on_error = true; break;
|
|
@ -15,12 +15,13 @@
|
||||||
You should have received a copy of the GNU General Public License along with
|
You should have received a copy of the GNU General Public License along with
|
||||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
showline.cpp
|
showline.c
|
||||||
Display a line on the terminal.
|
Display a line on the terminal.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
|
@ -15,11 +15,12 @@
|
||||||
You should have received a copy of the GNU General Public License along with
|
You should have received a copy of the GNU General Public License along with
|
||||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
util.cpp
|
util.c
|
||||||
Utility functions.
|
Utility functions.
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -30,12 +31,17 @@ char* strdup_safe(const char* string)
|
||||||
return string ? strdup(string) : NULL;
|
return string ? strdup(string) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* getenv_safe(const char* name, const char* def)
|
const char* getenv_safe_def(const char* name, const char* def)
|
||||||
{
|
{
|
||||||
const char* ret = getenv(name);
|
const char* ret = getenv(name);
|
||||||
return ret ? ret : def;
|
return ret ? ret : def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* getenv_safe(const char* name)
|
||||||
|
{
|
||||||
|
return getenv_safe_def(name, "");
|
||||||
|
}
|
||||||
|
|
||||||
bool array_add(void*** array_ptr,
|
bool array_add(void*** array_ptr,
|
||||||
size_t* used_ptr,
|
size_t* used_ptr,
|
||||||
size_t* length_ptr,
|
size_t* length_ptr,
|
|
@ -24,7 +24,8 @@
|
||||||
#define UTIL_H
|
#define UTIL_H
|
||||||
|
|
||||||
char* strdup_safe(const char* string);
|
char* strdup_safe(const char* string);
|
||||||
const char* getenv_safe(const char* name, const char* def = "");
|
const char* getenv_safe_def(const char* name, const char* def);
|
||||||
|
const char* getenv_safe(const char* name);
|
||||||
bool array_add(void*** array_ptr,
|
bool array_add(void*** array_ptr,
|
||||||
size_t* used_ptr,
|
size_t* used_ptr,
|
||||||
size_t* length_ptr,
|
size_t* length_ptr,
|
||||||
|
|
Loading…
Reference in New Issue