Convert sh to C.

This commit is contained in:
Jonas 'Sortie' Termansen 2016-02-28 23:38:08 +01:00
parent 8d58033846
commit 423285b855
7 changed files with 59 additions and 36 deletions

View File

@ -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

View File

@ -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);

View File

@ -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") )
{ {

View File

@ -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;

View File

@ -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>

View File

@ -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,

View File

@ -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,