diff --git a/command/command.go b/command/command.go index e74ae7f..ef4b76d 100644 --- a/command/command.go +++ b/command/command.go @@ -12,6 +12,7 @@ import ( "bbash/command/mv" "bbash/command/pwd" "bbash/command/rm" + "bbash/command/tail" "bbash/command/touch" "bbash/environment" "bbash/input_parser" @@ -56,6 +57,8 @@ func Run_command(in input_parser.Input, env *environment.Env) { mv.Mv(in, env) case "help": help.Help(in, env) + case "tail": + tail.Tail(in, env) default: if !run_by_path(in, env) { fmt.Println(fmt.Sprintf("No such command! (%s)", in.Instruction)) diff --git a/command/man/man.go b/command/man/man.go index 7cfed03..128815d 100644 --- a/command/man/man.go +++ b/command/man/man.go @@ -8,30 +8,31 @@ import ( func Man(in input_parser.Input, env *environment.Env) { switch in.Args_raw { - case "pwd": - fmt.Print("Output current working directory") - case "echo": - fmt.Print("Echoes the input argument") - case "ls": - fmt.Print("List Sources in the current working directory") - case "cd": - fmt.Print("Change to directory given in the argument") - case "man": - fmt.Print("Manual for the terminal options") - case "cat": - fmt.Print("Outputs the contents of the given file") - case "head": - fmt.Print("Outputs first lines of a given file. 10 if non provided. Argument ") - case "touch": - fmt.Print("Creates the given file") - case "rm": - fmt.Print("Removes the given file") - case "cp": - fmt.Print("Copies the given file. Argument: ") - case "mv": - fmt.Print("Moves a given file. Argument: ") - default: fmt.Println(fmt.Sprintf("No such command! (%s)", in.Instruction)) + case "pwd": + fmt.Print("Output current working directory") + case "echo": + fmt.Print("Echoes the input argument") + case "ls": + fmt.Print("List Sources in the current working directory") + case "cd": + fmt.Print("Change to directory given in the argument") + case "man": + fmt.Print("Manual for the terminal options") + case "cat": + fmt.Print("Outputs the contents of the given file") + case "head": + fmt.Print("Outputs first lines of a given file. 10 if none provided. Argument ") + case "touch": + fmt.Print("Creates the given file") + case "rm": + fmt.Print("Removes the given file") + case "cp": + fmt.Print("Copies the given file. Argument: ") + case "mv": + fmt.Print("Moves a given file. Argument: ") + case "tail": + fmt.Print("Outputs last lines of a given file. 10 if none or 0 is provided. Argument ") + default: + fmt.Println(fmt.Sprintf("No such command! (%s)", in.Instruction)) } } - - diff --git a/command/tail/tail.go b/command/tail/tail.go new file mode 100644 index 0000000..66a1cff --- /dev/null +++ b/command/tail/tail.go @@ -0,0 +1,84 @@ +package tail + +import ( + "bbash/environment" + "bbash/input_parser" + "bufio" + "bytes" + "fmt" + "io" + "os" + "strconv" + "strings" +) + +func Tail(in input_parser.Input, env *environment.Env) { + args := in.Args + var file_path string + var lines int + if len(args) >= 1 { + file_path = strings.TrimSpace(args[0]) + } else { + fmt.Print(fmt.Sprintf("No arguments provided")) + return + } + if len(args) == 2 { + lines1, err := strconv.Atoi(strings.TrimSpace(args[1])) + lines = lines1 + if err != nil { + fmt.Print(fmt.Sprintf("Second argument must be a integer")) + return + } + } + file, err := os.Open(file_path) + if err != nil { + fmt.Println(fmt.Sprintf("Error opening file: %s", err.Error())) + return + } + defer file.Close() + size, err := CountLines(file) + file.Seek(0, io.SeekStart) + scanner := bufio.NewScanner(file) + if lines == 0 { + for i := 0; i < size; i++ { + if !scanner.Scan() { + return + } + if i >= (size - 10) { + fmt.Println(fmt.Sprintf(scanner.Text())) + } + } + } else { + for i := 0; i < size; i++ { + if !scanner.Scan() { + return + } + if i >= (size - lines) { + fmt.Println(fmt.Sprintf(scanner.Text())) + } + } + } +} +func CountLines(r io.Reader) (int, error) { + var count int + var read int + var err error + var target []byte = []byte("\n") + + buffer := make([]byte, 32*1024) + + for { + read, err = r.Read(buffer) + if err != nil { + break + } + + count += bytes.Count(buffer[:read], target) + } + + if err == io.EOF { + return count, nil + } + + return count, err +} diff --git a/command/touch/touch.go b/command/touch/touch.go index efb6e57..c040d7e 100644 --- a/command/touch/touch.go +++ b/command/touch/touch.go @@ -9,7 +9,7 @@ import ( ) func Touch(in input_parser.Input, env *environment.Env) { - file_path := filepath.Join(env.Path, in.Args_raw) + file_path := filepath.Join(env.Path, in.Args[0]) _, err := os.Stat(file_path) if !os.IsNotExist(err) { fmt.Print(fmt.Sprintf("File alredy exist!")) @@ -22,6 +22,3 @@ func Touch(in input_parser.Input, env *environment.Env) { } defer file.Close() } - - - diff --git a/input_parser/input_parser.go b/input_parser/input_parser.go index 264e5a3..e14ce8b 100644 --- a/input_parser/input_parser.go +++ b/input_parser/input_parser.go @@ -36,8 +36,14 @@ func parse(input string) Input { var flags []string var args []string for _, arg := range split[1:] { - if len(arg) == 1 && arg[0] == '-' { + if len(arg) == 0 { continue + } else if len(arg) == 1 { + if arg[0] == '-' { + continue + } else { + args = append(args, strings.TrimSpace(arg)) + } } else if arg[0:2] == "--" { var result = strings.TrimSpace(arg) flags = append(flags, string(result[2:])) @@ -90,32 +96,21 @@ func input_str(env *environment.Env) string { case 4: // ^D input = "exit" goto loop_exit - case 27: // UPP - if r, _, _ := reader.ReadRune(); r != 91 { - break + case 65: // UPP + if history_index > 0 { + history_index-- + input = env.History[history_index] } case 66: // DOWN if history_index < len(env.History)-2 { history_index++ input = env.History[history_index] } else { - history_index = len(env.History)-1 + history_index = len(env.History) - 1 input = "" - if r, _, _ := reader.ReadRune(); r == 65 { // UPP - if history_index > 0 { - history_index-- - input = env.History[history_index] - } - } - if r, _, _ := reader.ReadRune(); r != 66 { //DOWN - if history_index < len(env.History)-1 { - history_index++ - input = env.History[history_index] - } else { - input = "" - } - } } + case 67: // LEFT + case 68: // RIGHT case 127: //packspace if len(input) > 0 { input = input[:len(input)-1] @@ -131,7 +126,7 @@ func input_str(env *environment.Env) string { fmt.Print(" > ") fmt.Print(input) } - loop_exit: +loop_exit: term.Restore(int(std_fd), term_restore) fmt.Println() return input diff --git a/input_parser/test_test.go b/input_parser/test_test.go index 6e3efd7..aeecfa1 100644 --- a/input_parser/test_test.go +++ b/input_parser/test_test.go @@ -14,7 +14,7 @@ func TestParse(t *testing.T) { } func TestInput(t *testing.T) { - + input := input_str(&environment.Env{}) fmt.Println(input) }