Indeed a really nice font and fully open source. Using it now at 11pt. See:
Sync subversion to github.com
This is a post that details on how to sync a subversion repository to git repository on github.com, and how to keep it in sync.
The following sites were instrumental in getting this to work:
There are a number of steps to take. From a bird’s eye view:
- Use
git svnto clone thesvnrepo to agitrepo; - Create a github
gitrepo; - Add a remote origin in your local git to the remote github repo;
- Use some SSH foo to use a separate SSH key for pushing to github.com.
Prerequisites
- We are working with the fictional svn repo located at
https://svn.example.net/example; git-svnis installed;sshis installed.
Clone the repository
Pandoc to RFC
This is an follow-up on this pandoc item in Dutch.
When writing RFC 4641 we directly wrote the XML. Needless to say is was kinda tedious even thought the XML of xml2rfc is very “light”.
Nowadays I’m a fan of the markdown syntax and especially the syntax as supported (created?) by Pandoc.
So for my next RFC (if ever!) I decided I wanted to use Pandoc. As xml2rfc uses XML
I thought the easiest way would be to create docbook XML and transform that using
XSLT.
Computer Languages
I have done programming in (or at least looked at) the following computer languages during my live. Of course the world is not a perfect place, but some languages out there are just plain awful.
-
BASIC - with line numbers! At the time (I was 11) didn’t know there was something else out there. Fun and easy language, although I never programmed in it ever again.
-
Pascal - After BASIC, there is no going back to Pascal. Only briefly looked at it in my youth and discarded it in favor for BASIC…
Prime sieve (in Go ofcourse)
After reading up on the prime sieve, and playing with Go for the past week I thought needed to implement this algorithm in Go and make it parallel.
I want to create a set (n in 2..N) goroutines. Each of these routines will check if it can divide a number (i) by n (integer division). If so the number i is not prime, otherwise it is given to the next goroutine. Communication between the goroutines is done via channels as in this example.
More Go
Still learning and playing with Go, I’ve
rewritten my
cat experiment, to
use a *bufio.Reader, which is more correct I think. I’m also slowly
wrapping my mind around the concept of
Interfaces. As a
non-OO programmer (C and non-OO Perl) is starting to see why this is
useful.
So today’s exercises:
- Write a cat implementation in Go. See below.
- Write a grep implementation in Go. See below.
Cat in go
package main
// A implementation of cat in Go
import (
"os";
"fmt";
"bufio";
"flag";
)
var numberFlag = flag.Bool("n", false, "number each line")
func cat(r *bufio.Reader) bool {
i := 1;
for {
buf, e := r.ReadBytes('\n');
if e == os.EOF {
break
}
if *numberFlag {
fmt.Fprintf(os.Stdout, "%5d %s", i, buf);
i++
} else {
fmt.Fprintf(os.Stdout, "%s", buf)
}
}
return true;
}
func main() {
flag.Parse();
if flag.NArg() == 0 {
cat(bufio.NewReader(os.Stdin))
}
for i := 0; i < flag.NArg(); i++ {
f, e := os.Open(flag.Arg(i), os.O_RDONLY, 0);
if e != nil {
fmt.Fprintf(os.Stderr, "%s: error reading from %s: %s\n",
os.Args[0], flag.Arg(i), e.String());
continue;
}
if !cat(bufio.NewReader(f)) {
os.Exit(1)
}
}
}
Grep in go
package main
// A implementation of Unix grep in Go
// TODO(mg) better error handling
import (
"os";
"fmt";
"bufio";
"regexp";
"flag";
)
var numberFlag = flag.Bool("n", false, "number each line")
var filenameFlag = flag.Bool("l", false, "print names of matching files")
func grep(r *bufio.Reader, reg string) (match bool) {
i := 0;
for {
buf, e := r.ReadBytes('\n');
i++;
if e == os.EOF {
break
}
if m, _ := regexp.Match(reg, buf); m == true {
match = true;
if *filenameFlag {
return match
}
if *numberFlag {
fmt.Fprintf(os.Stdout, "%5.d: %s", i, buf)
} else {
fmt.Fprintf(os.Stdout, "%s", buf)
}
}
}
return match;
}
func main() {
flag.Parse();
if flag.NArg() < 1 {
fmt.Fprintf(os.Stderr, "%s: missing regexp\n", os.Args[0]);
os.Exit(1);
}
if flag.NArg() == 1 {
if grep(bufio.NewReader(os.Stdin), flag.Arg(0)) {
if *filenameFlag {
fmt.Fprintf(os.Stdout, "(standard input)\n");
}
}
}
for i := 1; i < flag.NArg(); i++ {
f, e := os.Open(flag.Arg(i), os.O_RDONLY, 0);
if e != nil {
fmt.Fprintf(os.Stderr, "%s: error reading from %s: %s\n",
os.Args[0], flag.Arg(i), e.String());
continue;
}
if grep(bufio.NewReader(f), flag.Arg(0)) {
if *filenameFlag {
fmt.Fprintf(os.Stdout, "%s\n", flag.Arg(i))
}
}
}
}
cat in Go
After spending every free minute to Go I’m starting to get a feel
for the language. Every one has to start somewhere, so I decided to
“port” Unix utils to Go. I’m starting with cat, and thanks to
the Go tutorial this is the result.
package main
// An implementation of Unix cat in Go
import (
"os";
"fmt";
"flag";
)
func cat(filename string) bool {
const NBUF = 512;
var buf [NBUF]byte;
if f, e := os.Open(filename, os.O_RDONLY, 0); e != nil {
fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n",
filename, e.String());
return true;
} else {
for {
switch nr, _ := f.Read(&buf); true {
case nr < 0:
os.Exit(1)
case nr == 0: // EOF
return true
case nr > 0:
if nw, ew := os.Stdout.Write(buf[0:nr]); nw != nr {
fmt.Fprintf(os.Stderr,
"cat: error writing from %s: %s\n",
filename, ew.String());
return false;
}
}
}
}
return true;
}
func main() {
flag.Parse(); // implement -n TODO
if flag.NArg() == 0 {
cat("/dev/stdin")
}
for i := 0; i < flag.NArg(); i++ {
if !cat(flag.Arg(i)) {
os.Exit(1)
}
}
}
In something like 50 lines you have a cat program. I’m really starting
to like Go. Next up: extra features and a grep command.
First steps with Go
I joined the go-nuts mailing list a few days ago and it really feels good to receive 200+ emails per day again. Just like in the good old days before good spam filtering (and anti-spam laws).
I also re-watched the presentation Rob Pike gave for Google Tech Talks
on youtube.com. In there he presented the following program chain.go:
(Formatted with gofmt as it should)
package main
import (
"flag";
"fmt";
)
var ngoroutine = flag.Int("n", 100000, "how may")
func f(left, right chan int) { left <- 1+<-right }
func main() {
flag.Parse();
leftmost := make(chan int);
var left, right chan int = nil, leftmost;
for i := 0; i < *ngoroutine; i++ {
left, right = right, make(chan int);
go f(left, right);
}
right <- 0; // bang!
x := <-leftmost; // wait for completion
fmt.Println(x); // 100000
}
In this short program we make a chain of 100000 goroutines which are connected to each other. Each one adds 1 to the value it gets from its right neighbor. We start it of by giving the last one (right) a value of 0. Then we wait until they are finished and print it.
Go language
I’ve been wanting to learn (and do something) with the language
Erlang for over two years now. But every time
I fire up vim and start typing a get a this-is-not-Unix feeling (aka
Java-sickness). The syntax is just not right for me.
But now Google, by the creators of Unix and C, give us Go! Which promises to give us Erlang functionality in a C-like language. Just what I wanted!
Basically just follow the steps on golang.org. In short it boils down to:
gitvi (update)
A
colleague
of mine had some nice improvements to gitvi.
Right now gitvi can be edited by itself, because the magic
sequence $Hash$ is escaped like this
sed -i -e 's/\$[H]ash:.*\$/$H''ash$/' "$base"
(This was Ton’s idea)
Some other improvements like a -m MSG switch which allows
you to enter a commit message for all files you are editing.
And of course it then also needs to have a -h switch.
check if a directory is empty in bash
I had this small problem, how to you check if a directory is empty in the shell? Suppose I want to do
cmd po/*
this fails, if the po directory is empty, which in turn makes my
compile barf, but that is another story. I needed something to would
check the emptiness of the directory, and if it is not empty perform the
command, otherwise it skip it.
The trick here is to remember that if a shell wildcard can not be
expanded it will be left alone. So an unexpanded * will stay a *.