代码功能
扫描一个文件,如果文件中有-f flist1.f
, 那么新打开一个goroutine对flist1.f进行扫描, 如果是top.v
, 那么直接保存到一个列表里。
代码
package main
import (
"bufio"
"errors"
"fmt"
"io"
"log"
"os"
"regexp"
"strings"
)
type intlist []int
var dlog *log.Logger
type slist struct {
fn []string
count int
}
func main() {
logFile, err := os.Create("harriszh.log")
c := make(chan int)
defer logFile.Close()
if err != nil {
log.Fatalln("open file error!")
}
dlog = log.New(logFile, "[Debug]", log.Llongfile)
var s slist
path := os.Args[1]
s.getList(path, c)
i := 0
for i < s.count {
<-c
i++
}
s.showdec()
}
func (s *slist) showdec() {
dlog.Printf("########### BEGIN #################\n")
for _, k := range s.fn {
dlog.Printf("%s\n", k)
}
dlog.Printf("############# END ###############\n")
}
func (s *slist) getList(path string, c chan int) error {
scommentRe := regexp.MustCompile(`^\s*(.*?)\s*//.*`)
//the space is removed by TrimSpace
flistRe := regexp.MustCompile(`^-f\s+(.*)`)
fin, err := os.Open(path)
defer fin.Close()
if err != nil {
return errors.New("NOEXIST")
}
bufi := bufio.NewReader(fin)
for {
lineStat, err := bufi.ReadString('\n')
if err == io.EOF {
c <- 1
break
}
if err != nil {
fmt.Fprintf(os.Stderr, "can't read : %v\n", err)
os.Exit(1)
}
newline := strings.Replace(lineStat, "\n", "", -1)
linewc := scommentRe.ReplaceAllString(newline, "$1")
linewc = strings.TrimSpace(linewc)
if linewc != "" {
if flistRe.MatchString(linewc) {
newpath := flistRe.FindStringSubmatch(linewc)[1]
s.count++
go s.getList(newpath, c)
} else {
s.fn = append(s.fn, linewc)
}
}
}
return nil
}
测试文件
makefile
TARGET=getlist
SRC = getlist.go
default: build
help:
@echo "available commands:"
@echo " make build"
@echo " make run00"
@echo " make debug"
@echo " make clean"
build:
go build -gcflags "-N -l" -o ${TARGET} ${SRC}
release:
go build -ldflags "-s" -o ${TARGET} ${SRC}
# source /opt/go/src/runtime/runtime-gdb.py
# set args -input top.v -output out.v
# b main.main
run run00:
./${TARGET} flist.f
debug:
delve ./${TARGET}
clean:
rm -rf ${TARGET}
.PHONY: clean
flist.f
test00.v
-f f1.f
//comment0
test01.v
-f f2.f
//no f3.f
-f f3.f
f1.f
test10.v
//comment
test11.v
f2.f
test20.v
test21.v
//comment
## 问题
用了进程计数器,不过问题是还没等所有进程都完,main里面的for i < s.count就开始运行了
比较复杂的方案是把所有读取的行都通过chan返回,直到没有内容了
不知道有没有简单的方案
使用类型sync.WaitGroup,相关的操作要使用到该类型的Add方法,Done方法,Wait方法。