implemented tail and fixed errors in input parser when there is a spacebar but no argument and when there is a arg with len 1

This commit is contained in:
Laukka 2025-01-12 18:56:25 +01:00
parent a785c7df3b
commit a014ea71d2
4 changed files with 128 additions and 45 deletions

View File

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

View File

@ -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 <file> <number of lines>")
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: <source> <destination>")
case "mv":
fmt.Print("Moves a given file. Argument: <source> <destination>")
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 <file> <number of lines>")
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: <source> <destination>")
case "mv":
fmt.Print("Moves a given file. Argument: <source> <destination>")
case "tail":
fmt.Print("Outputs last lines of a given file. 10 if none or 0 is provided. Argument <file> <number of lines>")
default:
fmt.Println(fmt.Sprintf("No such command! (%s)", in.Instruction))
}
}

84
command/tail/tail.go Normal file
View File

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

View File

@ -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:]))
@ -81,7 +87,7 @@ func input_str(env *environment.Env) string {
for {
r_rune, _, err := reader.ReadRune()
if err != nil {
fmt.Print(fmt.Sprintf("Error reading user input: %s", err.Error()))
fmt.Print(fmt.Sprintf("Error reading user input: ", err.Error()))
}
switch r_rune {
case 3: // ^C
@ -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]