Added: Stdme as dependency

This commit is contained in:
Maieul BOYER 2024-04-28 17:07:05 +02:00
parent e1659508c6
commit 78f0707574
No known key found for this signature in database
11 changed files with 11 additions and 447 deletions

6
.gitmodules vendored
View file

@ -1,3 +1,3 @@
[submodule "stdme"] [submodule "shcat_c/stdme"]
path = stdme path = shcat_c/stdme
url = git@github.com:maix0/stdme.git url = git@github.com:Maix0/stdme.git

View file

@ -1 +0,0 @@
/target

View file

@ -1,7 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "parser-rs"
version = "0.1.0"

View file

@ -1,8 +0,0 @@
[package]
name = "parser-rs"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View file

@ -1,31 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* enum.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/28 12:44:05 by rparodi #+# #+# */
/* Updated: 2024/03/28 13:09:06 by rparodi ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef ENUM_H
#define ENUM_H
#include "./rust_type.h"
enum e_separator_op
{
Semi,
Fork,
};
enum e_pipeline_kind
{
Or,
And,
};
#endif

View file

@ -1,33 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* rust_type.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/28 12:50:51 by rparodi #+# #+# */
/* Updated: 2024/03/28 12:52:53 by rparodi ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef RUST_TYPE_H
#define RUST_TYPE_H
# define bool int
# define true 1
# define false 0
# define u8 unsigned char
# define u16 unsigned short
# define u32 unsigned int
# define u64 unsigned long long
# define i8 char
# define i16 short
# define i32 int
# define i64 long long
# define usize size_t
# define isize ssize_t
# define f32 float
# define f64 double
#endif

View file

@ -1,29 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* shcat.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/28 12:42:55 by rparodi #+# #+# */
/* Updated: 2024/03/28 12:53:50 by rparodi ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef SHCAT_H
#define SHCAT_H
# include <unistd.h>
# include <fcntl.h>
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <sys/types.h>
# include <sys/wait.h>
# include <stdlib.h>
# include <stdarg.h>
# include <stddef.h>
# include "./enum.h"
# include "./rust_type.h"
#endif

View file

@ -1,331 +0,0 @@
#![allow(dead_code)]
use std::{borrow::Cow, collections::VecDeque, convert::Infallible as Never, pin::Pin};
type WORD = String;
type Rule2 = String;
type Rule3 = String;
struct SourceFile {
cmds: Vec<CompleteCommands>,
}
struct CompleteCommands {
// each Pipeline Must have a Separator, but the
// last Pipeline is optional
list: Vec<(Pipeline, Option<SeparatorOp>)>,
}
enum SeparatorOp {
Semi, /* ; */
Fork, /* & */
}
struct Pipeline {
bang: bool, // placed before the seqence
kind: Option<PipelineKind>, // placed after the seqence
seq: Vec<Commands>, // each cmd are piped into the next
}
enum PipelineKind {
Or, /* || */
And, /* && */
}
enum Commands {
Simple(SimpleCommand),
Compound(Never),
FuncDef(Never),
}
struct SimpleCommand {
prefix: Vec<CmdPrefix>,
cmd: Vec<WORD>, // First is rule 7a, then 7b
suffix: Vec<CmdSuffix>,
}
enum CmdPrefix {
IoRedirect(IoRedirect),
Assigment(Assigment),
}
enum CmdSuffix {
IoRedirect(IoRedirect),
Word(WORD),
}
struct IoRedirect {
io_file: Option<usize>,
io_kind: IoKind,
}
enum IoKind {
IoFile(IoFile),
IoHere(IoHere),
}
enum IoFile {
Less { filename: Rule2 }, /* < */
Greater { filename: Rule2 }, /* > */
LessAnd { filename: Rule2 }, /* <& */
GreaterAnd { filename: Rule2 }, /* >& */
DoubleGreater { filename: Rule2 }, /* >> */
LessGreater { filename: Rule2 }, /* <> */
Clobber { filename: Rule2 }, /* >| */
}
enum IoHere {
Dless { here_end: Rule3 }, /* << */
DlessDash { here_end: Rule3 }, /* <<- */
}
// Rule 7
struct Assigment {
key: WORD,
value: WORD,
}
#[derive(Default)]
struct TokenizerState<'input> {
current_pos: usize,
input: &'input str,
remaining: &'input str,
invalid_quote: bool,
_marker: std::marker::PhantomPinned,
}
impl<'input> TokenizerState<'input> {
fn new(input: &'input str) -> Self {
Self {
current_pos: 0,
remaining: input,
invalid_quote: false,
input,
_marker: std::marker::PhantomPinned,
}
}
}
// Cow<'input, str> is either a owned string (so it'll have to be free'd, basically it is an `String`
// or it is an borrow string, so an &'input str, which doesn't need to be free (or at least by us)
#[derive(Debug, Clone)]
enum Token<'input> {
SingleQuote {
val: Cow<'input, str>,
start_pos: usize,
},
DoubleQuote {
val: Cow<'input, str>,
start_pos: usize,
},
WhiteSpace {
val: Cow<'input, str>,
start_pos: usize,
},
Word {
val: Cow<'input, str>,
start_pos: usize,
},
}
fn tokenizer<'state, 'input: 'state>(
state: &'state mut TokenizerState<'input>,
) -> impl Iterator<Item = Token<'input>> + 'state {
state.current_pos = 0;
std::iter::from_fn(move || {
let state = &mut *state;
let mut chars = state.remaining.chars().peekable();
let mut len = 1;
let mut escaped = false;
let Some(chr) = chars.next() else {
return None;
};
match chr {
'\'' => {
while let Some(s) = chars.peek().copied() {
if s == '\'' {
break;
}
len += 1;
chars.next();
}
let skip = chars.peek() == Some(&'\'');
state.invalid_quote |= !skip;
let old_current = state.current_pos;
state.current_pos += len;
let old_remaining = state.remaining;
state.remaining = &state.remaining[(len + skip as usize)..];
return Some(Token::SingleQuote {
val: old_remaining[1..len].into(),
start_pos: old_current,
});
}
'"' => {
while let Some(s) = chars.peek().copied() {
if !escaped && s == '\"' {
break;
}
len += 1;
escaped = chars.next() == Some('\\');
}
let skip = chars.peek() == Some(&'\"');
state.invalid_quote |= !skip;
let old_current = state.current_pos;
state.current_pos += len;
let old_remaining = state.remaining;
state.remaining = &state.remaining[(len + skip as usize)..];
return Some(Token::DoubleQuote {
val: old_remaining[1..len].into(),
start_pos: old_current,
});
}
_ => {}
}
let was_whitespace = chr.is_ascii_whitespace();
while let Some(&chr) = chars.peek() {
if chr.is_ascii_whitespace() && !escaped && !was_whitespace {
let old_current = state.current_pos;
state.current_pos += len;
let old_remaining = state.remaining;
state.remaining = &state.remaining[len..];
return Some(Token::Word {
val: old_remaining[..len].into(),
start_pos: old_current,
});
} else if !chr.is_ascii_whitespace() && was_whitespace {
let old_current = state.current_pos;
state.current_pos += len;
let old_remaining = state.remaining;
state.remaining = &state.remaining[len..];
return Some(Token::WhiteSpace {
val: old_remaining[..len].into(),
start_pos: old_current,
});
}
len += 1;
escaped = chars.next() == Some('\\');
}
let old_current = state.current_pos;
state.current_pos += len;
let old_remaining = state.remaining;
state.remaining = &state.remaining[len..];
Some(if was_whitespace {
Token::WhiteSpace {
val: old_remaining[..len].into(),
start_pos: old_current,
}
} else {
Token::Word {
val: old_remaining[..len].into(),
start_pos: old_current,
}
})
})
}
// This isn't a C thingy, it is just needed to make rust happy
struct TokenizerWrapper<'input> {
_marker: std::marker::PhantomPinned,
first_pass: TokenizerState<'input>,
iter: Box<dyn Iterator<Item = Token<'input>> + 'input>,
}
impl<'input> TokenizerWrapper<'input> {
fn new(s: TokenizerState<'input>) -> Pin<Box<Self>> {
let mut value = Box::new(std::mem::MaybeUninit::<Self>::uninit());
unsafe {
let ptr = value.as_mut_ptr();
std::ptr::write(std::ptr::addr_of_mut!((*ptr).first_pass), s);
std::ptr::write(
std::ptr::addr_of_mut!((*ptr).iter),
Box::new(tokenizer(&mut *std::ptr::addr_of_mut!((*ptr).first_pass))),
);
std::mem::transmute(Pin::new_unchecked(value))
}
}
}
impl<'input> TokenizerWrapper<'input> {
fn next(self: &mut Pin<Box<Self>>) -> Option<Token<'input>> {
unsafe { Pin::into_inner_unchecked(self.as_mut()).iter.next() }
}
}
// end of rust thingy
struct ExpenderState<'input> {
// These will be inserted when a substitution is made, like $HOME
// if it is "$HOME", then no splitting should be done, so if there is any stuff that needs to
// be pushed, then push it, otherwise get the next token from `iter`, expend if needed and
// voila
need_push: VecDeque<ExpendedToken<'input>>,
// This is because of the way I wrote the rust
// stuff, returning iterator instead of an token everytime I call a function and stuff, it
// shouldn't be reflected into the C code, as we will just call 'get_next_token(&state)' and it
// will give us the next token (or EOF if no more token are present)
tokenizer: Pin<Box<TokenizerWrapper<'input>>>,
}
#[derive(Debug, Clone)]
enum ExpendedToken<'input> {
SingleQuote {
val: Cow<'input, str>,
start_pos: usize,
},
DoubleQuote {
val: Cow<'input, str>,
start_pos: usize,
},
WhiteSpace {
val: Cow<'input, str>,
start_pos: usize,
},
Word {
val: Cow<'input, str>,
start_pos: usize,
},
}
impl<'input> ExpenderState<'input> {
fn new(input: &'input str) -> Self {
let wrapper = TokenizerWrapper::new(TokenizerState::new(input));
Self {
need_push: VecDeque::new(),
tokenizer: wrapper,
}
}
}
fn expend<'state, 'input: 'state>(
input: &'state mut ExpenderState<'input>,
) -> impl Iterator<Item = ExpendedToken<'input>> + 'state {
std::iter::from_fn(|| {
if !input.need_push.is_empty() {
input.need_push.pop_front()
} else {
input.tokenizer.next().map(|t| match t {
Token::Word { val, start_pos } => ExpendedToken::Word { val, start_pos },
Token::DoubleQuote { val, start_pos } => {
ExpendedToken::DoubleQuote { val, start_pos }
}
Token::SingleQuote { val, start_pos } => {
ExpendedToken::SingleQuote { val, start_pos }
}
Token::WhiteSpace { val, start_pos } => {
ExpendedToken::WhiteSpace { val, start_pos }
}
})
}
})
}
fn main() {
for line in std::io::stdin().lines() {
let line = line.unwrap();
let mut state = ExpenderState::new(&line);
println!("line is = '{line}'");
println!("token are = {:?}", expend(&mut state).collect::<Vec<_>>());
}
}

View file

@ -6,7 +6,7 @@
# By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ # # By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ # # +#+#+#+#+#+ +#+ #
# Created: 2023/11/12 11:05:05 by rparodi #+# #+# # # Created: 2023/11/12 11:05:05 by rparodi #+# #+# #
# Updated: 2024/04/13 20:18:33 by rparodi ### ########.fr # # Updated: 2024/04/28 17:05:10 by maiboyer ### ########.fr #
# # # #
# **************************************************************************** # # **************************************************************************** #
@ -23,7 +23,7 @@ CC = cc
RM = rm -rf RM = rm -rf
# Flags # Flags
CFLAGS = -Werror -Wextra -Wall -Wno-unused-command-line-argument -g3 -MMD -lreadline CFLAGS = -Werror -Wextra -Wall -Wno-unused-command-line-argument -g3 -MMD -lreadline -I./libft
# Sources # Sources
LIB = ./libft/ft_bzero.c \ LIB = ./libft/ft_bzero.c \
@ -84,7 +84,7 @@ fclean: clean
re: header fclean all re: header fclean all
# Dependences for all # Dependences for all
$(NAME): $(OBJ) $(LIB_OBJ) $(NAME): $(OBJ) $(LIB_OBJ) $(OBJDIRNAME)/libme.a
@mkdir -p $(OBJDIRNAME) @mkdir -p $(OBJDIRNAME)
@mkdir -p $(OBJDIRNAME)/$(LIBDIRNAME) @mkdir -p $(OBJDIRNAME)/$(LIBDIRNAME)
@mkdir -p $(OBJDIRNAME)/$(SRCDIRNAME) @mkdir -p $(OBJDIRNAME)/$(SRCDIRNAME)
@ -128,6 +128,10 @@ footer:
@printf "$(GOLD) '\"' '\"'$(END)\n" @printf "$(GOLD) '\"' '\"'$(END)\n"
@printf ' $(GREY)The compilation is$(END) $(GOLD)finish$(END)\n $(GREY)Have a good $(END)$(GOLD)correction !$(END)\n' @printf ' $(GREY)The compilation is$(END) $(GOLD)finish$(END)\n $(GREY)Have a good $(END)$(GOLD)correction !$(END)\n'
$(OBJDIRNAME)/libme.a:
@$(MAKE) --no-print-directory -C ./stdme/ LIB_NAME="$(realpath ./$(stdme))/" "BUILD_DIR=$(shell realpath ./$(OBJDIRNAME))"
pull: pull:
@printf "$(GREEN)Pulling Submodules$(END)\n" @printf "$(GREEN)Pulling Submodules$(END)\n"
@git submodule init @git submodule init

1
shcat_c/stdme Submodule

@ -0,0 +1 @@
Subproject commit dc3c8ff9dc6f396a8fefd4ad89883e5285171b23

1
stdme

@ -1 +0,0 @@
Subproject commit b3ec36536db39e871e06e6073c05bf2f965adf99