Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
34 views7 pages

Minishel - Algorithm

The document outlines the pseudo code for a MINISHELL algorithm, detailing the main program flow, parsing, tokenization, execution, and memory management. It includes functions for handling commands, redirection, pipes, and signal management, as well as built-in and external command execution. The time and space complexity of the algorithm is also provided, indicating O(n) for both aspects.

Uploaded by

eliebalaa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
34 views7 pages

Minishel - Algorithm

The document outlines the pseudo code for a MINISHELL algorithm, detailing the main program flow, parsing, tokenization, execution, and memory management. It includes functions for handling commands, redirection, pipes, and signal management, as well as built-in and external command execution. The time and space complexity of the algorithm is also provided, indicating O(n) for both aspects.

Uploaded by

eliebalaa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

MINISHELL ALGORITHM - PSEUDO CODE

==================================

MAIN PROGRAM FLOW:


------------------

FUNCTION main(argc, argv, env):


INITIALIZE mini structure
SET mini.in = duplicate(STDIN)
SET mini.out = duplicate(STDOUT)
SET mini.exit = FALSE
SET mini.ret = 0

CALL reset_fds(mini)
CALL env_init(mini, env)
CALL secret_env_init(mini, env)
CALL increment_shell_level(mini.env)

WHILE mini.exit == FALSE:


CALL sig_init()
CALL parse(mini)

IF mini.start != NULL AND check_line(mini, mini.start):


CALL minishell(mini)

CALL free_token(mini.start)
END WHILE

CALL free_env(mini.env)
CALL free_env(mini.secret_env)
RETURN mini.ret
END FUNCTION

PARSING ALGORITHM:
------------------

FUNCTION parse(mini):
SET signal handlers for SIGINT and SIGQUIT

IF mini.ret != 0:
PRINT "🤬 "
ELSE:
PRINT "😎 "

PRINT "minishell ▸ "

READ line from stdin using get_next_line()

IF EOF received:
SET mini.exit = TRUE
PRINT "exit"
RETURN

UPDATE mini.ret based on signal status

IF quote_check(mini, line) returns error:


RETURN

SET line = space_line(line) // Add spaces around separators


IF line starts with '$':
MARK first character for expansion

SET mini.start = get_tokens(line)


CALL free(line)
CALL squish_args(mini)

FOR each token in mini.start:


IF token.type == ARG:
CALL type_arg(token, 0)
END FOR
END FUNCTION

TOKENIZATION ALGORITHM:
-----------------------

FUNCTION get_tokens(line):
SET prev = NULL
SET next = NULL
SET i = 0

SKIP initial whitespace

WHILE line[i] exists:


SET sep = ignore_sep(line, i)
SET next = next_token(line, &i)

LINK next.prev = prev


IF prev exists:
LINK prev.next = next

SET prev = next


CALL type_arg(next, sep)
SKIP whitespace
END WHILE

IF next exists:
SET next.next = NULL

FIND and return first token


END FUNCTION

FUNCTION next_token(line, i):


ALLOCATE new token
SET j = 0
SET quote_char = ' '

WHILE line[i] exists AND (line[i] != ' ' OR inside quotes):


IF quote_char == ' ' AND line[i] is quote:
SET quote_char = line[i]
INCREMENT i
ELSE IF quote_char != ' ' AND line[i] == quote_char:
SET quote_char = ' '
INCREMENT i
ELSE IF line[i] == '\' (escape character):
INCREMENT i
ADD line[i] to token.str[j]
INCREMENT i, j
ELSE:
ADD line[i] to token.str[j]
INCREMENT i, j
END WHILE

SET token.str[j] = '\0'


RETURN token
END FUNCTION

EXECUTION ALGORITHM:
--------------------

FUNCTION minishell(mini):
SET token = next_run(mini.start, NOSKIP)

IF first token is redirection type:


SET token = mini.start.next

WHILE mini.exit == FALSE AND token exists:


SET mini.charge = TRUE
SET mini.parent = TRUE
SET mini.last = TRUE

CALL redir_and_exec(mini, token)

CALL reset_std(mini)
CALL close_fds(mini)
CALL reset_fds(mini)

WAIT for child process to complete


GET exit status
UPDATE mini.ret if this was last command

IF this is child process:


FREE memory and exit

SET mini.no_exec = FALSE


SET token = next_run(token, SKIP)
END WHILE
END FUNCTION

REDIRECTION AND EXECUTION ALGORITHM:


------------------------------------

FUNCTION redir_and_exec(mini, token):


SET prev = prev_sep(token, NOSKIP)
SET next = next_sep(token, NOSKIP)
SET pipe = 0

IF prev.type == TRUNC:
CALL redir(mini, token, TRUNC)
ELSE IF prev.type == APPEND:
CALL redir(mini, token, APPEND)
ELSE IF prev.type == INPUT:
CALL input(mini, token)
ELSE IF prev.type == PIPE:
SET pipe = minipipe(mini)

IF next exists AND next.type != END AND pipe != 1:


RECURSIVELY CALL redir_and_exec(mini, next.next)

IF (prev.type == END OR prev.type == PIPE OR prev == NULL)


AND pipe != 1 AND mini.no_exec == FALSE:
CALL exec_cmd(mini, token)
END FUNCTION

COMMAND EXECUTION ALGORITHM:


----------------------------

FUNCTION exec_cmd(mini, token):


IF mini.charge == FALSE:
RETURN

SET cmd = cmd_tab(token) // Convert tokens to string array

FOR each string in cmd:


SET cmd[i] = expansions(cmd[i], mini.env, mini.ret)
END FOR

IF cmd[0] == "exit" AND no pipe:


CALL mini_exit(mini, cmd)
ELSE IF is_builtin(cmd[0]):
SET mini.ret = exec_builtin(cmd, mini)
ELSE IF cmd exists:
SET mini.ret = exec_bin(cmd, mini.env, mini)

CALL free_tab(cmd)
CLOSE pipe file descriptors
SET mini.charge = FALSE
END FUNCTION

VARIABLE EXPANSION ALGORITHM:


-----------------------------

FUNCTION expansions(arg, env, ret):


CALCULATE new_arg_len = arg_alloc_len(arg, env, ret)
ALLOCATE new_arg with new_arg_len + 1

SET i = 0, j = 0

WHILE i < new_arg_len AND arg[j] exists:


WHILE arg[j] == EXPANSION:
INCREMENT j

IF arg[j] == '\0' OR not alphanumeric AND arg[j] != '?':


ADD '$' to new_arg[i]
INCREMENT i
ELSE:
CALL insert_var(expansion_struct, arg, env, ret)
END WHILE

SET new_arg[i] = arg[j]


INCREMENT i, j
END WHILE

SET new_arg[i] = '\0'


RETURN new_arg
END FUNCTION
BUILT-IN EXECUTION ALGORITHM:
-----------------------------

FUNCTION exec_builtin(args, mini):


SET result = 0

SWITCH args[0]:
CASE "echo":
SET result = ft_echo(args)
CASE "cd":
SET result = ft_cd(args, mini.env)
CASE "pwd":
SET result = ft_pwd()
CASE "env":
CALL ft_env(mini.env)
CASE "export":
CALL ft_export(args, mini.env, mini.secret_env)
CASE "unset":
CALL ft_unset(args, mini)
END SWITCH

RETURN result
END FUNCTION

EXTERNAL COMMAND EXECUTION ALGORITHM:


-------------------------------------

FUNCTION exec_bin(args, env, mini):


FIND PATH environment variable

IF PATH not found:


RETURN magic_box(args[0], args, env, mini)

SPLIT PATH by ':' into bin array

FOR each directory in bin:


SET path = check_dir(bin[i], args[0])
IF path found:
BREAK
END FOR

IF path found:
RETURN magic_box(path, args, env, mini)
ELSE:
RETURN magic_box(args[0], args, env, mini)
END FUNCTION

FUNCTION magic_box(path, args, env, mini):


SET pid = fork()

IF pid == 0 (child process):


CONVERT env to string array

IF path contains '/':


CALL execve(path, args, env_array)

HANDLE error and exit


ELSE (parent process):
WAIT for child process
RETURN exit status
END FUNCTION

PIPE HANDLING ALGORITHM:


------------------------

FUNCTION minipipe(mini):
CREATE pipe file descriptors
SET pid = fork()

IF pid == 0 (child process):


CLOSE write end of pipe
REDIRECT pipe read end to stdin
SET mini.pipin = pipe read fd
SET mini.parent = FALSE
RETURN 2
ELSE (parent process):
CLOSE read end of pipe
REDIRECT pipe write end to stdout
SET mini.pipout = pipe write fd
SET mini.last = FALSE
RETURN 1
END FUNCTION

REDIRECTION ALGORITHM:
---------------------

FUNCTION redir(mini, token, type):


CLOSE current output fd

IF type == TRUNC:
OPEN token.str for write with truncate
ELSE:
OPEN token.str for write with append

IF open failed:
PRINT error message
SET mini.ret = 1
SET mini.no_exec = TRUE
RETURN

REDIRECT stdout to file


END FUNCTION

FUNCTION input(mini, token):


CLOSE current input fd
OPEN token.str for read

IF open failed:
PRINT error message
SET mini.ret = 1
SET mini.no_exec = TRUE
RETURN

REDIRECT stdin to file


END FUNCTION

SIGNAL HANDLING ALGORITHM:


--------------------------

FUNCTION sig_int(code):
IF g_sig.pid == 0 (at prompt):
PRINT newline and new prompt
SET g_sig.exit_status = 1
ELSE (command running):
PRINT newline
SET g_sig.exit_status = 130

SET g_sig.sigint = 1
END FUNCTION

FUNCTION sig_quit(code):
IF g_sig.pid != 0 (command running):
PRINT "Quit: " + signal number
SET g_sig.exit_status = 131
SET g_sig.sigquit = 1
ELSE:
CLEAR display artifacts
END FUNCTION

MEMORY MANAGEMENT ALGORITHM:


----------------------------

FUNCTION free_token(start):
WHILE start exists:
SET next = start.next
FREE start.str
FREE start
SET start = next
END WHILE
END FUNCTION

FUNCTION free_env(env):
WHILE env exists:
SET next = env.next
FREE env.value
FREE env
SET env = next
END WHILE
END FUNCTION

TIME COMPLEXITY: O(n) where n is the length of input


SPACE COMPLEXITY: O(n) for token storage and environment variables

You might also like