Previous

10.3.5.2. Formatted input
a)

PROC getf = (REF FILE f, [ ] UNION (INTYPE, FORMAT)x) VOID:
  IF opened OF f THEN
    FOR k TO UPB x
    DO CASE set read mood (f); set char mood (f); x[k] IN
        ( FORMAT format): associate format (f, format),
        ( INTYPE it):
          BEGIN INT j := 0;
            PICTURE picture, [ ] SIMPLIN y = STRAIGHTIN it;
            WHILE(j +:=- 1) <= UPB y
            DO BOOL incomp := FALSE;
                get next picture (f, TRUE, picture); set read mood (f);
                [ 1: UPB (i OF picture)] SINSERT sinsert;
                CASE p OF pidec IN
                  ( PATTERN pattern):
                    BEGIN
                    [ 1: UPB (frames OF pattern)] SFRAME sframes;
                    ( staticize frames (frames OF pattern, sframes).
                        staticize insertion (i OF picture, sinsert));
                    STRING s;
                    INT radix =
                      ( type OF pattern >= 6 | type OF pattern - 4 | 10);
                    indit string (f, s, sframes, radix);
                    CASE type OF pattern IN
                        ¢ integral ¢
                        ( y[j] |
                          « (REF {L} INT ii):
                            incomp := string to {l} int (s, 10, ii) »
                        | incomp := TRUE),
                        ¢ real¢
                        ( y[j] |
                          « (REF {L} REAL rr):
                            incomp := string to {l} real (s, rr) »
                        | incomp := TRUE),
                        ¢ boolean¢
                        ( y[j] |
                          ( REF BOOL bb): bb := s = flip
                        | incomp := TRUE),
                        ¢ complex ¢
                        ( y[j] |
                          « (REF {L} COMPL zz):
                            ( INT i, BOOL bi, b2; char in string ("I", i, s);
                              b1 := string to {l} real (s [ : i-1], re OF zz);
                              b2 := string to {l} real (s [i+1: ], im OF zz);
                              incomp := ~ (b1 & b2 ))»
                        | incomp := TRUE),
                        ¢ string ¢
                        ( y[j] |
                          ( REF CHAR cc):
                            ( UPB s = 1 | cc := s [1] | incomp := TRUE),
                        ( y[j] |
                          ( REF CHAR cc):
                            ( UPB s = 1 | cc := s [1] | incomp := TRUE),
                          ( REF [ ] CHAR ss):
                            ( UPB ss - LWB ss + 1 = UPB s | ss [@1] := s
                            | incomp := TRUE),
                          ( REF STRING ss): ss := s
                        | incomp := TRUE)
                    OUT
                        ¢ bits ¢
                        ( y[j] |
                          « (REF {L} BITS lb):
                            IF {L} INT i; string to {l} int (s, radix, i)
                            THEN lb := BIN i
                            ELSE incomp := TRUE
                            FI»
                        | incomp := TRUE)
                    ESAC
                    END, 
                    ( CPATTERN choice):
                      BEGIN
                          [ 1: UPB (i OF choice) SINSERT si;
                            staticize insertion (i OF choice, si);
                            get insertion (f, si);
                            INT c = c OF cpos OF f, CHAR kk;
                            INT k := 0, BOOL found := FALSE;
                            WHILE k < UPB (c OF choice) & ~ found
                            DO k +:= 1;
                                [ 1: UPB ((c OF choice) [k])] SINSERT si;
                                BOOL bool := TRUE;
                                staticize insertion ((c OF choice, [k ], si);
                                      STRING s;
                                    FOR i TO UPB s
                                    DO s PLUSAB
                                          ( sa OF si[i] | (STRING ss): ss) * rep OF si[i]
                                    OD;   
                                    FOR jj TO UPB s
                                    WHILE bool := bool & ~ line ended (f)
                                          & ~ logical file ended (f)
                                    DO get char(f, kk); bool := kk = s[jj] OD;
                                    ( ~ (found = bool) | set char number (f, c))
                            OD; 
                            IF ~ found THEN incomp := TRUE
                            ELSE
                                CASE type OF choice IN
                                    ¢ boolean ¢
                                    ( y [j] |
                                      ( REF BOOL b): b := k = 1
                                    | incomp := TRUE),
                                    ¢ integral ¢
                                    ( y [j] |
                                      ( REF INT i): i := k
                                    | incomp := TRUE)
                                ESAC
                            FI;
                            staticize insertion (i OF picture, sinsert)
                      END,
                       
                    ( FPATTERN fpattern): 
                      BEGIN do fpattern (f, fpattern, TRUE);
                          FOR i TO UPB sinsert DO sinsert [i] := (0, "") OD;
                      END,
                            
                    ( GPATTERN gpattern):
                      ( [1: UPB (i OF gpattern) ] SINSERT si;
                        ( staticize insertion (i OF gpattern, si),
                          staticize insertion (i OF picture, sinsert));
                        get insertion (f, si);
                        get (f, y [j])),
                    ( VOID):
                      ( j -:= 1; staticize insertion (i OF picture, sinsert))
                ESAC;
                IF incomp
                THEN set read mood (f);
                    ( ~(value error mended OF f) (f) | undefined)
                      get insertion (f, sinsert)
            OD
          END
      ESAC OD
  ELSE undefined
  FI;

b)

PROC {?}indit string = (REF FILE f, REF STRING s, [ ] SFRAME sf, INT radix) VOID:
  BEGIN
      BOOL supp, zs := TRUE, sign found := FALSE, space found := FALSE,
      nosign := FALSE, INT sp:=1, rep;
      PRIO ! = 8;
                        
      OP ! = (STRING s, CHAR c) CHAR :
        # expects a character contained in 's'; if the character read is not in
's', the event routine corresponding to 'on char error' is called with the sugge
stion 'c' #
        IF CHAR k; checkpos (f); get char (f, k);
            char in string (k, LOC INT , s)
        THEN k
        ELSE CHAR sugg := c;
            CHAR cc = IF (char error mended OF f) (f, sugg) THEN
                ( char in string (sugg, LOC INT , s) | sugg | undefined; c)
            ELSE undefined; c   
            FI;
            set read mood (f); cc
        FI;
      OP ! = (CHAR s, c) CHAR : STRING (s) ! c;
      [ ] CHAR good digits = "0123456789abcdef" [ : radix];
      s := "+";
      FOR k TO UPB sf
      DO SFRAME sfk =sf[k]; supp := supp OF fsk;
          get insertion (f, si OF sfk);  
          TO rep OF sfk
          DO CHAR marker = marker OF sfk;
              IF marker = "d" THEN
                  s PLUSAB (supp | "0" | good digits! "0"); zs := TRUE
              ELIF marker = "a" THEN
                  s PLUSAB (supp | "0"   
                    | CHAR c = ((zs | " " | "" )+gooddigits)!"0";
                      ( c /= " " | zs := FALSE); c)
              ELIF marker = "u" ¦ marker = "+" THEN
                  IF sign found
                  THEN zs := FALSE; a PLUSAB ("0123456789"! "0")
                  ELSE CHAR c = ("+-"+(marker = "u" | " " | "" ))! "+";
                      ( c = "+" ¦ c = "-" | sign found := TRUE; s[sp] := c)
                  FI
              ELIF marker = "v" ¦ marker = "-" THEN
                  IF sign found
                  THEN zs := FALSE; z PLUSAB ("0123456789"! "0")
                  ELIF CHAR c; space found
                  THEN c := "+- 0123456789"!"+";
                      ( c = "+" ¦ c = "-" | signfound := TRUE; s [sp] := c
                      |: c /= " " | zs := FALSE; sign found := TRUE; s PLUSAB c)
                  ELSE c := "+- "! "+";
                      ( c = "+" ¦ c = "-" | sign found := TRUE; s [sp] := c
                      | space found := TRUE)
                  FI
              ELIF marker ="." THEN
                  s PLUSAB (supp | "." | "."! ".")
              ELIF marker = "e" THEN
                  s PLUSAB (supp | "\io" | "\io\e"! "\io"; "\io"); sign found := FALSE;
                  zs := TRUE; s PLUSAB "+"; sp := UPB s
              ELIF marker = "i" THEN  
                  s PLUSAB (supp | "I " | "iI"! "I"; "I");
                  sign found := FALSE; zs := TRUE; s PLUSAB "+"; sp := UPB s
              ELIF marker = "b" THEN  
                  s PLUSAB (flip + flop) ! flop; no sign := TRUE
              ELIF marker = "a" THEN
                  s PLUSAB (supp | " " | CHAR c; check pos (f); get char (f, c);
                      c);
                  no sign := TRUE
              ELIF marker = "r"
              THEN SKIP
              FI
          OD
      OD;
      IF no sign THEN s := s[2: ] FI
  END;

 
Next