modernc.org/knuth@v0.0.4/mf/internal/trap/api.go (about)

     1  // Copyright 2023 The Knuth Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package trap is the TRAP variant of the METAFONT program by D. E. Knuth,
     6  // transpiled to Go.
     7  //
     8  //	http://mirrors.ctan.org/systems/knuth/dist/mf/mf.web
     9  package trap // modernc.org/knuth/mf/internal/trap
    10  
    11  import (
    12  	// Required for go:embed
    13  	_ "embed"
    14  	"fmt"
    15  	"io"
    16  	"runtime/debug"
    17  	"unsafe"
    18  
    19  	"modernc.org/knuth"
    20  )
    21  
    22  //go:embed mf.pool
    23  var pool string
    24  
    25  // program MF; {all file names are defined dynamically}
    26  
    27  // Main executes the tangle program using the supplied arguments.
    28  func Main(stdin io.Reader, stdout, stderr io.Writer, opener func(string) (io.Reader, error)) (mainErr error) {
    29  	defer func() {
    30  		switch x := recover().(type) {
    31  		case nil:
    32  			// ok
    33  		case signal:
    34  			switch {
    35  			case mainErr == nil:
    36  				mainErr = fmt.Errorf("aborted")
    37  			default:
    38  				mainErr = fmt.Errorf("aborted: %v", mainErr)
    39  			}
    40  		case knuth.Error:
    41  			mainErr = x
    42  		default:
    43  			mainErr = fmt.Errorf("PANIC %T: %[1]v, error: %v\n%s", x, mainErr, debug.Stack())
    44  		}
    45  	}()
    46  
    47  	prg := &prg{
    48  		baseFile: knuth.NewBinaryFile(nil, nil, int(unsafe.Sizeof(memoryWord{})), opener),
    49  		gfFile:   knuth.NewBinaryFile(nil, nil, 1, nil),
    50  		logFile:  knuth.NewTextFile(nil, nil, nil),
    51  		poolFile: knuth.NewPoolFile(pool),
    52  		stderr:   knuth.NewTextFile(nil, stderr, nil),
    53  		termIn:   knuth.NewTextFile(stdin, nil, nil),
    54  		termOut:  knuth.NewTextFile(nil, stdout, nil),
    55  		tfmFile:  knuth.NewBinaryFile(nil, nil, 1, nil),
    56  	}
    57  	for i := range prg.inputFile {
    58  		prg.inputFile[i] = knuth.NewTextFile(nil, nil, opener)
    59  	}
    60  	prg.main()
    61  	return nil
    62  }