## todo list :

- **builtins :**
	- ~~echo~~
	- echo -n
	- cd <relative path>
	- cd <absolute path>
	- pwd
	- export
	- unset
	- env
	- ~~exit~~
- '  *(ignore any special characters)* --> [ressource](https://linuxhandbook.com/quotes-in-bash/)
- "  *(ignore any special characters except '$')*
- unclosed quotes ?
- **redirection :**
	- `>` *input*
	- `>` *output*
	- `<<` *read input until empty line -- doesn't update history*
	- `>>` *redirect and append*
- |
- $
- $?
- **signals :**
	- ^C  *close process*
	- ^D  *exit minishell*
	- ^\  *do nothing*
- history

--> [source of a minishell with an interesting README](https://git.42l.fr/Fabien/minishell)

---

[methode arbre binaire](https://fr.wikipedia.org/wiki/Arbre_binaire#Transformation_d'un_arbre_quelconque_en_un_arbre_binaire)

```
EXEMPLE :
	'something "is 'new'" here'
		something is new here
			is new
				new
	'something "is"'new'  here'
		something is
		new
		here

ARCHITECTURE :
	all
	.	pipes
	.	.	redirections (program or file)
	.	.	.	arguments (nom arg arg arg ...)
	.	.	.	.	special characters ($)
	.	.	.	.	.
EXEMPLE :	.	.	.
	[sort < ./prgrm 'arg1 '$VARIABLE" arg3" | grep "word.$EXTENSION" | wc -l > file]
	.	[sort < ./prgrm 'arg1 '$VARIABLE" arg3"]
	.	.	[sort]	.
	.	.	[./prgrm 'arg1 '$VARIABLE" arg3"]
	.	.	.	[./prgrm]
	.	.	.	['arg1 ']
	.	.	.	[$VARIABLE]
	.	.	.	.	[$VARIABLE]
	.	.	.	[" arg3"]
	.	[grep "word.$EXTENSION"]
	.	.	.	[grep]
	.	.	.	["word.$EXTENSION"]
	.	.	.	.	[$EXTENSION]
	.	[wc -l > file]
	.	.	[wc -l]
	.	.	.	[wc]
	.	.	.	[-l]
	.	.	[file]
```

---

Ordre Interpreteur :
1) Couper les mots (comment faire ? je ne vois pas comment gerer ce genre de bordel ci dessous)
```
shell@prompt> ./arg_test 'mot1 '$NAME" mot2"
	argc = 2
	argv[0] = |./arg_test|
	argv[1] = |mot1 Tour-Lemdows10 mot2|
shell@prompt>
```
2) $ - Env Vars Expand. if $VAR not set, expand to nothing("").
	Dont save it as "" argument for fonctions, just delete.

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

Commandes dans variables d'env fonctionne :
```
shell@prompt> export VAR_TEST="echo"
shell@prompt> $VAR_TEST "string :)"
string :)
shell@prompt>
```
--------------

l'expension des variables dans des variables est fait au moment de export(),
donc pas de recursivité infini et de prise de tête au moment de l'interpretation.
Il suffit de faire "une passe" pour dévelloper les variables,
aucun besoin de refaire des passes succesives pour d'éventuels nouvelles variables aprés dévellopement :

```
export :
	export VAR_TEST="test $NAME"
dans l'env :
	NAME="Tour-Lemdows10"
	VAR_TEST="test Tour-Lemdows10"

export :
	export NAME="Un nouveau nom"
dans l'env :
	NAME="Un nouveau nom"
	VAR_TEST="test Tour-Lemdows10"
```
```
export :
	export VAR_TEST="test $VAR_TEST"
dans l'env :
	VAR_TEST="test test Tour-Lemdows10"

export :
	export VAR_TEST="test $VAR_TEST"
dans l'env :
	VAR_TEST="test test test Tour-Lemdows10"
```

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

Tests pour Hugo, pour illustrer les pipes simultanés :
```
sleep 3 ; sleep 3 ; sleep 3 ; sleep 3
sleep 3 | sleep 3 | sleep 3 | sleep 3

sleep 5 ; ls | wc -l
sleep 5 | ls | wc -l
```

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

argv passé à execv(), telle quelle ou aprés avoir trouvé le PATH ?
exemple, si j'apelle "cat file.txt", dans un shell genre bash/zsh,
la commande cat recoit t'elle :
```
argv[0] == "cat"
argv[1] == "file.txt"
```
OU
```
argv[0] == "/bin/cat"
argv[1] == "file.txt"
```

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

A test sur bash et minishell :

	echo "phrase quelquonque" > file1 > file2 > file3

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

Pour les builtins dans une commande simple :
1) detecter la commande builtin
2) Ne pas fork() et execv().
	A la place, chercher la fonction aproprié dans un tableau contenant les pointeurs vers les fonctions builtins.
	Puis appeler la fonction dans le genre : builtin(ft_arrlen(cmd->argv), cmd->argv, &c).


Pour les builtins dans une commande complexe (pipes, redirections, here doc, ...) :
1) detecter la commande builtin
2) fork()
3) Ne pas execv().
	A la place, chercher la fonction aproprié dans un tableau contenant les pointeurs vers les fonctions builtins.
	Puis appeler la fonction dans le genre : builtin(ft_arrlen(cmd->argv), cmd->argv, &c).
4) aprés la fin de la commande, free toute la mémoire du sous_processus, puis quitter le sous_processus en renvoyant le return de la commande builtin.
par exemple comme ça :
	free_exit(&c, builtin(ft_arrlen(cmd->argv), cmd->argv, &c))


Peut-être faire un champ "void *builtin_command" dans une struct "cmd" pour contenir l'adresse de la fonction builtin.
```
typedef struct s_cmd
{
	char	**argv;
	pid_t	pid;
	void	*builtin_command;
}				t_cmd;
```
Si la commande n'est pas builtin

	cmd->builtin_command == NULL.

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

tester comment ce comporte minishell aprés le crash d'une commande (message sigfault comme dans bash ? Autres ?)

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

Implementer les exit status dans les builtins

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

EDIT : Aprés reflexion et verification, ça semble en effet le mieux a faire.
En l'etat le return de la derniere fonction marche correctement, j'ai verifier pas de problemes.
Si le child est deja fini avant l'apelle de wait, ça return quand même.
Cependant, pour optimiser la liberation des resources dés que possible,
il semble plus logique de liberer les sous_processus dés qu'ils ont terminés,
et donc, pas nécessairement dans l'ordre de la pipeline.
Donc, un waitpid() sur la derniere commande pour sauvegarder le retour,
puis wait() pour les autres, l'ordre n'ayant plus d'importance.

Revoir le wait() de mon pipex. Il n'est peut être pas correct.
En effet, j'attend que le premier process se ferme avec waitpid(), puis le deuxiéme, le troisiéme, ...
Mais en faite, il vaudrait peut être mieux attendre qu'un sous process QUELQUONQUE se ferme, puis le suivant, et le suivant, ...

Vu le fonctionnement des pipes, je crois que ce n'est pas toujours la premiere commande qui ce termine en premier,
et donc, qu'il ne faudrait pas attendre la fin de la premiere commande en particulier,
mais d'une commande QUELQUONQUE avec wait() plutot que waitpid().

IDÉE :
Attendre avec waitpid() la derniere commande pour obtenir son status, puis wait() en boucle les autres commandes,
et enfin renvoyer le status.

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

Faire des test avec 

	"env -i ./minishell"
pour voir si ça ne crash pas.

Normal si le comportement attendu n'est pas correct (en l'absence de PATH et tout ça) mais ça ne devrait pas crasher pour autant.

