Skip to content

The File Format

Chris Michael edited this page Oct 7, 2026 · 1 revision

Pudu

The File Format

An environment file is lines of KEY=value. This chapter reads one text with every form in it, using a Source.Text so nothing touches the disk:

module Ex02Format

import Std.Io as Io
import Std.Map as Map
import PuduLangEnvironment.Loader as Loader
import PuduLangEnvironment.Options as Options
import PuduLangEnvironment.Source as Source

const LINES: Array[Str] = [
  "# comments and blank lines are skipped",
  "",
  "  # indented comments too",
  "export REGION=eu-west",
  "HOST = localhost   # an inline comment",
  "PATH_LIKE=C:\\tools\\bin",
  "GREETING='Hello, $USER'",
  "URL=\"https://$\{HOST\}:$\{PORT:-8080\}/$REGION\"",
  "QUOTED=\"she said \\\"hi\\\"\"",
  "MULTI=\"first line",
  "second line\""
]

export fn main() -> Int {
  let options = Options.defaults().withSources(&[Source.Text("example", LINES.join("\n"))]).withExportSyntax().withExpansion().withTrimValues()
  match Loader.readOver(&options, &Map.fromPairs(&[("USER", "ada")])) {
    case Ok(values) => {
      for pair in values.entries() { let _shown = Io.writeLine(pair[0] + " = " + show(pair[1])) }
      0
    }
    case Err(_) => 1
  }
}

Output:

GREETING = "Hello, $USER"
HOST = "localhost"
MULTI = "first line\nsecond line"
PATH_LIKE = "C:\\tools\\bin"
QUOTED = "she said \"hi\""
REGION = "eu-west"
URL = "https://localhost:8080/eu-west"

readOver answers the merged values as a Map, expanding over the process environment it is given instead of the real one. Its entries come back in key order.

The rules

Line Reading
blank, or first visible character # skipped, indented comments included
no = after the first character, or an empty key skipped
KEY=value the key is trimmed; the value is everything after the first =, kept as written unless trimming is on
export KEY=value read as KEY when export syntax is on; exporter=1 keeps its key
KEY=value # note with inline comments on (the default), the value ends before a # that follows a space or tab
KEY='value' single quotes: kept literally, never expanded
KEY="value" double quotes: expanded when expansion is on
a quote not closed on its line the value continues on the next lines, keeping the line breaks
a quote never closed the file is refused with UnclosedQuote, naming the key and the line it opened on

Inside quotes, an escaped quote (\" or \') stands for the quote and \\ for one backslash. Every other backslash stays as written, so Windows paths keep theirs. Text after a closing quote is ignored. Lines ending in \r\n read the same as lines ending in \n.

Options that change the reading

Option Default Chain
trimValues false withTrimValues, withoutTrimValues
exportSyntax false withExportSyntax, withoutExportSyntax
inlineComments true withInlineComments, withoutInlineComments
expansion false withExpansion, withoutExpansion

Related

Clone this wiki locally