doc: add Defer, Panic, and Recover article

Originally published on The Go Programming Language Blog, August 4 2010.

http://blog.golang.org/2010/08/defer-panic-and-recover.html

Update #2547

R=golang-dev, r, r
CC=golang-dev
https://golang.org/cl/5479053
diff --git a/doc/progs/defer.go b/doc/progs/defer.go
new file mode 100644
index 0000000..f52278a
--- /dev/null
+++ b/doc/progs/defer.go
@@ -0,0 +1,53 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains the code snippets included in "Defer, Panic, an Recover."
+
+package main
+
+import (
+	"fmt"
+	"io"
+	"os"
+)
+
+func a() {
+	i := 0
+	defer fmt.Println(i)
+	i++
+	return
+}
+// STOP OMIT
+
+func b() {
+	for i := 0; i < 4; i++ {
+		defer fmt.Print(i)
+	}
+}
+// STOP OMIT
+
+func c() (i int) {
+	defer func() { i++ }()
+	return 1
+}
+// STOP OMIT
+
+// Intial version.
+func CopyFile(dstName, srcName string) (written int64, err error) {
+	src, err := os.Open(srcName)
+	if err != nil {
+		return
+	}
+
+	dst, err := os.Create(dstName)
+	if err != nil {
+		return
+	}
+
+	written, err = io.Copy(dst, src)
+	dst.Close()
+	src.Close()
+	return
+}
+// STOP OMIT
diff --git a/doc/progs/defer2.go b/doc/progs/defer2.go
new file mode 100644
index 0000000..be6791d
--- /dev/null
+++ b/doc/progs/defer2.go
@@ -0,0 +1,56 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains the code snippets included in "Defer, Panic, an Recover."
+
+package main
+
+import "fmt"
+import "io" // OMIT
+import "os" // OMIT
+
+func main() {
+	f()
+	fmt.Println("Returned normally from f.")
+}
+
+func f() {
+	defer func() {
+		if r := recover(); r != nil {
+			fmt.Println("Recovered in f", r)
+		}
+	}()
+	fmt.Println("Calling g.")
+	g(0)
+	fmt.Println("Returned normally from g.")
+}
+
+func g(i int) {
+	if i > 3 {
+		fmt.Println("Panicking!")
+		panic(fmt.Sprintf("%v", i))
+	}
+	defer fmt.Println("Defer in g", i)
+	fmt.Println("Printing in g", i)
+	g(i + 1)
+}
+// STOP OMIT
+
+// Revised version.
+func CopyFile(dstName, srcName string) (written int64, err error) {
+	src, err := os.Open(srcName)
+	if err != nil {
+		return
+	}
+	defer src.Close()
+
+	dst, err := os.Create(dstName)
+	if err != nil {
+		return
+	}
+	defer dst.Close()
+
+	return io.Copy(dst, src)
+}
+// STOP OMIT
diff --git a/doc/progs/run b/doc/progs/run
index e90e307..dd58639 100755
--- a/doc/progs/run
+++ b/doc/progs/run
@@ -20,25 +20,41 @@
 	$GC file.go
 fi
 
+defer_panic_recover="
+	defer.go 
+	defer2.go 
+"
+
+effective_go="
+	eff_bytesize.go
+	eff_qr.go 
+	eff_sequence.go
+"
+
+go_tutorial="
+	cat.go 
+	cat_rot13.go 
+	echo.go 
+	file.go
+	helloworld.go 
+	helloworld3.go 
+	print.go 
+	print_string.go 
+	server.go 
+	server1.go 
+	sieve.go 
+	sieve1.go 
+	sort.go 
+	sortmain.go 
+	strings.go 
+	sum.go 
+"
+
 for i in \
-	helloworld.go \
-	helloworld3.go \
-	echo.go \
-	cat.go \
-	cat_rot13.go \
-	sum.go \
-	sort.go \
-	sortmain.go \
-	print.go \
-	print_string.go \
-	sieve.go \
-	sieve1.go \
-	server1.go \
-	strings.go \
-	eff_bytesize.go\
-	eff_qr.go \
-	eff_sequence.go\
-	go1.go\
+	$defer_panic_recover \
+	$effective_go \
+	$go_tutorial \
+	go1.go \
 ; do
 	$GC $i
 done