Added flag to print match indices, and to enable multi-line mode

master
Aadhavan Srinivasan 1 month ago
parent 2569f52552
commit c694c47be7

@ -126,7 +126,7 @@ func shuntingYard(re string) []postfixNode {
6. If current character is '{', find the appropriate numeric specifier (range start, range end). Apply the range to the postfixNode at the end of outQueue.
*/
c := re_postfix[i]
if isAlphaNum(c) {
if isNormalChar(c) {
outQueue = append(outQueue, newPostfixNode(c))
continue
}
@ -379,7 +379,9 @@ func main() {
// 1. Without '-v': Prints only matches. Prints a newline after every match.
// 2. With '-v': Substitutes all matches with empty string.
onlyFlag := flag.Bool("o", false, "Print only colored content. Overrides -l.")
lineFlag := flag.Bool("l", false, "Only print lines with a match (or with no matches, if -v is enabled")
lineFlag := flag.Bool("l", false, "Only print lines with a match (or with no matches, if -v is enabled (similar to grep's default")
multiLineFLag := flag.Bool("t", false, "Multi-line mode. Treats newline just like any character.")
printMatchesFlag := flag.Bool("p", false, "Prints start and end index of each match. Can only be used with '-t' for multi-line mode.")
flag.Parse()
// -l and -o are mutually exclusive: -o overrides -l
@ -402,16 +404,50 @@ func main() {
var test_str string
var test_runes []rune // Rune-slice representation of test_str
var err error
// Create reader for stdin and writer for stdout // End index is one more than last index of match
var linesRead bool // Whether or not we have read the lines in the file
// Create reader for stdin and writer for stdout
reader := bufio.NewReader(os.Stdin)
out := bufio.NewWriter(os.Stdout)
re_postfix := shuntingYard(re)
startState := thompson(re_postfix)
// Read every string from stdin until we encounter an error. If the error isn't EOF, panic.'
for test_str, err = reader.ReadString('\n'); err == nil; test_str, err = reader.ReadString('\n') {
for true {
if linesRead {
break
}
if !(*multiLineFLag) {
// Read every string from stdin until we encounter an error. If the error isn't EOF, panic.
test_str, err = reader.ReadString('\n')
if err != nil {
if err == io.EOF {
linesRead = true
} else {
panic(err)
}
}
} else {
// Multi-line mode - read every line of input into a temp. string.
// test_str will contain all lines of input (including newline characters)
// as one string.
var temp string
for temp, err = reader.ReadString('\n'); err == nil; temp, err = reader.ReadString('\n') {
test_str += temp
}
// Assuming err != nil
if err == io.EOF {
linesRead = true
} else {
panic(err)
}
}
test_runes = []rune(test_str)
matchIndices := findAllMatches(startState, []rune(test_runes))
if *printMatchesFlag {
for _, idx := range matchIndices {
fmt.Printf("%s\n", idx.toString())
}
continue
}
// Decompose the array of matchIndex structs into a flat unique array of ints - if matchIndex is {4,7}, flat array will contain 4,5,6
// This should make checking O(1) instead of O(n)
indicesToPrint := new_uniq_arr[int]()
@ -463,7 +499,4 @@ func main() {
panic(err)
}
}
if err != io.EOF {
panic(err)
}
}

Loading…
Cancel
Save