home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / C / MAXONC3_6OF8.DMS / in.adf / LIBSRC.LHA / LIBSRC / scanf.asm < prev    next >
Encoding:
Assembly Source File  |  1994-12-15  |  8.3 KB  |  526 lines

  1.  
  2. * Himpelsoft C++ Project:
  3. * Library-Modul "scanf"
  4. * Jens Gelhar 06.11.91, 18.06.94, 03.12.94, 15.12.94
  5.  
  6.     xdef    _scanf,scanf__PCce
  7.     xdef    _fscanf,fscanf__P06streamPCce
  8.     xdef    _sscanf,sscanf__PCcPCce
  9.  
  10.     xref    lib_double2float
  11.     xref    _std__in,fgetc__P06stream,ungetc__iP06stream
  12.     xref    strtovl__PCcPPci,strtouvl__PCcPPci,strtod__PCcPPc
  13.  
  14. _sscanf:
  15. sscanf__PCcPCce:
  16.     movem.l    d2-d7/a2-a6,-(a7)
  17.     move.l    11*4+4(a7),a6        ; Inputstring
  18.     move.l    11*4+8(a7),a1        ; Formatstring
  19.     lea    11*4+12(a7),a2        ; Parameter
  20.     sub.l    a0,a0
  21.     bra.b    schtjampf
  22.  
  23. _scanf:
  24. scanf__PCce:
  25.     movem.l    d2-d7/a2-a6,-(a7)
  26.     lea    _std__in,a0
  27.     move.l    11*4+4(a7),a1        ; Formatstring
  28.     lea    11*4+8(a7),a2        ; Parameter
  29.     bra.b    schtjampf
  30.  
  31. _fscanf:
  32. fscanf__P06streamPCce:
  33.     movem.l    d2-d7/a2-a6,-(a7)
  34.     move.l    11*4+4(a7),a0        ; Stream
  35.     move.l    11*4+8(a7),a1        ; Formatstring
  36.     lea    11*4+12(a7),a2        ; Parameter
  37. schtjampf: ; Einsprung
  38.     clr.l -(a7)             ; Return-Value für d0
  39.     moveq #-1,d7            ; Zeichenzähler
  40.     bsr Get
  41.     tst.l d0
  42.     bpl.b Loop
  43.     move.l d0,(a7)
  44.     bra End
  45. Loop    ; Hauptschleife (erstes Zeichen schon in d0)
  46.     bsr OverreadFormat
  47.     tst.b d1
  48.     beq End
  49.     cmp.b #'%',d1
  50.     beq.b Prozent
  51. Expect    ; Zeichen vergleichen:
  52.     bsr Overread
  53.     cmp.b d0,d1
  54.     bne ForgetLine              ; paßt nicht!
  55.     bsr Get
  56.     bra.b Loop
  57. Prozent    move.b (a1)+,d1
  58.     cmp.b #'*',d1
  59.     bne.b noDummy
  60.     sub.l a3,a3
  61.     move.b (a1)+,d1
  62.     bra.b Dummy
  63. noDummy    move.l (a2)+,a3         ; Zielvector
  64. Dummy    move.w #$7FFF,d6            ; Feldbreite
  65.     cmp.b #'0',d1
  66.     blo.b Arg
  67.     cmp.b #'9',d1
  68.     bhi.b Arg
  69.     moveq #0,d6
  70.     move.b d1,d6
  71. Feldbr    sub.w #'0',d6
  72.     moveq #0,d1
  73.     move.b (a1)+,d1
  74.     cmp.b #'0',d1
  75.     blo.b Arg
  76.     cmp.b #'9',d1
  77.     bhi.b Arg
  78.     mulu #10,d6
  79.     add.w d1,d6
  80.     bra.b Feldbr
  81. Arg    and.w #$FF,d1
  82.     cmp.b #'h',d1
  83.     beq.b Laenge
  84.     cmp.b #'l',d1
  85.     beq.b Laenge
  86.     cmp.b #'L',d1
  87.     bne.b Scan
  88. Laenge    asl.w #8,d1
  89.     move.b (a1)+,d1
  90. Scan    ; Scan(doppel)code in d1.w:
  91.     cmp.w #'s',d1
  92.     beq String
  93.     cmp.w #'c',d1
  94.     beq Char
  95.     cmp.w #'[',d1
  96.     beq.b Pattern
  97.     cmp.w #'%',d1
  98.     beq GetProzent
  99.     cmp.b #'n',d1
  100.     beq Number
  101.     ; numerisch: d6 maximal Puffergröße
  102.     cmp.w #StkBuf-4,d6
  103.     bls.b scn1
  104.     moveq #StkBuf-4,d6
  105. scn1    move.w d1,d2
  106.     cmp.b #'d',d1
  107.     beq Dez
  108.     cmp.b #'i',d1
  109.     beq Int
  110.     cmp.b #'x',d1
  111.     beq Hex
  112.     cmp.b #'p',d1
  113.     beq Hex
  114.     cmp.b #'o',d1
  115.     beq Oct
  116.     cmp.b #'e',d1
  117.     beq Float
  118.     cmp.b #'f',d1
  119.     beq Float
  120.     cmp.b #'g',d1
  121.     beq Float
  122.     ; Formatfehler:
  123.     bra End
  124.  
  125. Pattern:
  126.     move.l a1,a4    ; Pattern-Anfang
  127.     tst.b (a1)
  128.     beq.b pat2
  129. pat1    addq.l #1,a1
  130.     tst.b (a1)
  131.     beq.b pat2
  132.     cmp.b #']',(a1)
  133.     bne.b pat1
  134.     move.l a1,d4
  135.     addq.l #1,a1    ; Klammer am Ende nicht akzeptieren
  136.     bra.b pat3
  137. pat2    ; Pattern von a4 bis a1:
  138.     move.l a1,d4
  139. pat3    sub.l a4,d4     ; Anfang a4, Länge d4
  140.     addq.l #1,(a7)
  141.     tst.w d6
  142.     beq.b patEnd
  143. patLoop    ; d0 in Pattern?
  144.     move.l a4,a5
  145.     move.w d4,d5
  146.     beq.b patEnd
  147.     cmp.b #'^',(a4)
  148.     bne.b patCheck
  149.     addq.l #1,a5
  150.     subq.w #1,d5
  151.     beq.b patNein
  152. patCheck cmp.b (a5)+,d0
  153.     beq.b patJa
  154.     cmp.b #'-',(a5)
  155.     bne.b patNext
  156.     cmp.w #3,d5
  157.     blt.b patNext
  158.     ; Minus und nicht am Ende:
  159.     subq.w #2,d5
  160.     addq.l #1,a5
  161.     cmp.b (a5)+,d0
  162.     bhi.b patNext
  163.     cmp.b -3(a5),d0
  164.     bhs.b patJa
  165. patNext    ; weitersuchen:
  166.     subq.w #1,d5
  167.     bne.b patCheck
  168. patNein    ; nicht im Pattern:
  169.     cmp.b #'^',(a4)
  170.     bne.b patEnd
  171.     bra.b patOK
  172. patJa    ; im Pattern:
  173.     cmp.b #'^',(a4)
  174.     beq.b patEnd
  175. patOK    ; Zeichen paßt
  176.     move.l a3,d1
  177.     beq.b patPut
  178.     move.b d0,(a3)+         ; Zeichen in String schreiben
  179. patPut    bsr Get
  180.     tst.l d0
  181.     bmi.b patEnd
  182.     subq.w #1,d6
  183.     bne.b patLoop
  184. patEnd    move.l a3,d1
  185.     beq Loop
  186.     clr.b (a3)
  187.     bra Loop
  188.  
  189. String:
  190.     bsr OverreadLN
  191.     cmp.b #10,d0
  192.     bne.b s0
  193.     bsr Get                 ; höchstens ein LF akzeptieren
  194.     bsr OverreadLN
  195. s0    tst.l d0
  196.     bmi Loop
  197.     addq.l #1,(a7)
  198.     cmp.b #10,d0
  199.     bne.b sLoop
  200.     move.l a3,d1
  201.     beq Loop
  202.     clr.b (a3)
  203.     bra Loop
  204. sLoop    tst.w d6
  205.     beq Loop
  206.     move.l a3,d1
  207.     beq.b s1
  208.     move.b d0,(a3)+
  209.     clr.b (a3)
  210. s1    bsr Get
  211.     tst.l d0
  212.     bmi Loop
  213.     cmp.b #' ',d0
  214.     bls Loop
  215.     subq.w #1,d6
  216.     bra.b sLoop
  217.  
  218. Char:    tst.l d0
  219.     bmi Loop
  220.     addq.l #1,(a7)
  221.     cmp.w #$7FFF,d6
  222.     blo.b cloop
  223.     moveq #1,d6
  224. cloop    tst.w d6
  225.     beq Loop
  226.     move.l a3,d2
  227.     beq.b ch1
  228.     move.b d0,(a3)+
  229. ch1    bsr Get
  230.     tst.l d0
  231.     bmi Loop
  232.     cmp.b #' ',d0
  233.     bls Loop
  234.     subq.w #1,d6
  235.     bra.b cloop
  236.  
  237. StkBuf    = 80
  238.  
  239. Dez:    bsr Overread
  240.     lea -StkBuf(a7),a7
  241.     cmp.w #StkBuf-4,d6
  242.     bls.b dz1
  243.     moveq #StkBuf-4,d6
  244. dz1    move.l a7,a4
  245.     bsr Sign
  246.     bsr DigitSequence
  247.     moveq #10,d4
  248. Convert    ; String a7 bis a4 mit Basis d4
  249.     exg    d0,d4
  250.     clr.b    (a4)
  251.     move.b    (a7),d1
  252.     beq.b    dzErr
  253.     move.l    a0,-(a7)
  254.     move.l    d0,-(a7)
  255.     clr.l    -(a7)
  256.     pea    12(a7)
  257.     cmp.b    #'-',d1
  258.     beq.b    dzSig
  259.     cmp.b    #'+',d1
  260.     beq.b    dzSig
  261.     jsr    strtouvl__PCcPPci
  262.     bra.b    dzUnSig
  263. dzSig    jsr    strtovl__PCcPPci
  264. dzUnSig    lea    12(a7),a7
  265.     move.l    (a7)+,a0
  266.     lea    StkBuf(a7),a7
  267.     addq.l #1,(a7)
  268.     lsr.w #8,d2
  269.     cmp.w #'L',d2
  270.     beq.b PutDouble
  271.     cmp.w #'h',d2
  272.     beq.b PutWord
  273. Put    move.l a3,d2
  274.     beq.b GoOn
  275.     move.l d0,(a3)
  276. GoOn    move.l d4,d0            ; gemerktes Zeichen
  277.     bra Loop
  278.  
  279. PutDouble:
  280.     move.l a3,d2
  281.     beq Loop
  282.     movem.l d0/d1,(a3)
  283.     bra.b GoOn
  284.  
  285. PutWord:
  286.     move.l a3,d2
  287.     beq Loop
  288.     move.w d0,(a3)
  289.     bra.b GoOn
  290.  
  291. dzErr    lea StkBuf(a7),a7
  292. ForgetLine:    ; Fehler: Rest der Zeile überlesen
  293.     tst.l d0
  294.     bmi End
  295.     tst.b d0
  296.     beq End
  297.     cmp.b #10,d0
  298.     beq End
  299.     bsr Get
  300.     bra.b ForgetLine
  301.  
  302.  
  303. Int:    bsr Overread
  304.     lea -StkBuf(a7),a7
  305.     move.l a7,a4
  306.     bsr Sign
  307.     cmp.b #'0',d0
  308.     bne.b int2
  309.     bsr Accept
  310.     cmp.b #'x',d0
  311.     beq.b inHx
  312.     cmp.b #'X',d0
  313.     beq.b inHx
  314.     bra.b ocLoop
  315. int2    bsr DigitSequence
  316.     moveq #10,d4
  317.     bra Convert
  318.  
  319. Hex:    bsr Overread
  320.     lea -StkBuf(a7),a7
  321.     move.l a7,a4
  322.     bsr Sign
  323.     cmp.b #'0',d0
  324.     bne.b hx2
  325.     bsr Accept
  326.     cmp.b #'x',d0           ; "x" unterschlagen
  327.     beq.b inHx
  328.     cmp.b #'X',d0
  329.     bne.b hx2
  330. inHx    subq.w #1,d6
  331.     bsr Get
  332.     bra.b hx2
  333. hxLoop    bsr Accept
  334. hx2    cmp.b #'0',d0
  335.     blo.b hx3
  336.     cmp.b #'9',d0
  337.     bls.b hxLoop
  338.     cmp.b #'A',d0
  339.     blo.b hx3
  340.     cmp.b #'F',d0
  341.     bls.b hxLoop
  342.     cmp.b #'a',d0
  343.     blo.b hx3
  344.     cmp.b #'f',d0
  345.     bls.b hxLoop
  346. hx3    moveq #16,d4
  347.     bra Convert
  348.  
  349. Oct:    bsr Overread
  350.     lea -StkBuf(a7),a7
  351.     move.l a7,a4
  352.     bsr Sign
  353. ocLoop    cmp.b #'0',d0
  354.     blo.b oc1
  355.     cmp.b #'7',d0
  356.     bhi.b oc1
  357.     bsr Accept
  358.     bra.b ocLoop
  359. oc1    moveq #8,d4
  360.     bra Convert
  361.  
  362. Float:    bsr Overread
  363.     lea -StkBuf(a7),a7
  364.     move.l a7,a4
  365.     clr.w (a7)
  366.     bsr.b Sign
  367.     bsr DigitSequence
  368.     bsr.b    Punkt
  369.     bsr    DigitSequence
  370.     tst.b    (a7)
  371.     beq dzErr               ; ungültiger Anfang
  372.     cmp.b #'e',d0
  373.     beq.b flExp
  374.     cmp.b #'E',d0
  375.     bne.b flAcc
  376. flExp    bsr.b Accept
  377.     move.l a4,d1
  378.     bsr.b Sign
  379.     bsr.b DigitSequence
  380.     cmp.l a4,d1
  381.     bne.b flAcc
  382.     ; hinter "e" kam nichts mehr:
  383.     move.l d0,-(a7)
  384.     move.b -(a4),d0
  385.     bsr Unget
  386.     move.l (a7)+,d0
  387. flAcc    clr.b (a4)
  388.     tst.b (a7)
  389.     beq dzErr
  390.     move.l d0,d4
  391.     move.l    a0,-(a7)
  392.     clr.l    -(a7)
  393.     pea    8(a7)
  394.     jsr    strtod__PCcPPc
  395.     addq.l    #8,a7
  396.     move.l    (a7)+,a0
  397.     lea    StkBuf(a7),a7
  398.     addq.l    #1,(a7)
  399.     lsr.w #8,d2
  400.     tst.b d2
  401.     bne PutDouble
  402.     jsr lib_double2float
  403.     bra Put         ; float
  404.  
  405. Punkt:    ; Dezimalpunkt akzeptieren
  406.     cmp.b #'.',d0
  407.     beq.b Accept
  408.     bra.b ret
  409.  
  410. Sign:    ; +,- akzeptieren
  411.     cmp.b #'+',d0
  412.     beq.b Accept
  413.     cmp.b #'-',d0
  414.     bne.b ret
  415. Accept:    tst.w d6
  416.     beq.b sgEnd
  417.     bmi.b sgEnd
  418.     subq.w #1,d6
  419.     move.b d0,(a4)+
  420.     bra Get
  421. sgEnd    moveq #-1,d0
  422. ret    rts
  423.  
  424. DigitSequence:
  425.     cmp.b #'0',d0
  426.     blo.b ret
  427.     cmp.b #'9',d0
  428.     bhi.b ret
  429.     tst.w d6
  430.     beq.b ret
  431.     subq.w #1,d6
  432.     move.b d0,(a4)+
  433.     bsr Get
  434.     bra.b DigitSequence
  435.  
  436. Number:    ; Anzahl zurückgeben
  437.     move.l a3,d2
  438.     beq Loop
  439.     cmp.w #'hn',d1
  440.     beq.b numW
  441.     move.l d7,(a3)+
  442.     cmp.w #'ln',d1
  443.     bne Loop
  444.     clr.l (a3)
  445.     bra Loop
  446. numW    move.w d7,(a3)
  447.     bra Loop
  448.  
  449. GetProzent:    ; "%" akzeptieren
  450.     moveq #'%',d1
  451.     move.l a3,d1
  452.     beq Expect
  453.     subq.l #4,a2    ; Pointer brauchen wir nicht
  454.     bra Expect
  455.  
  456. End:    cmp.b #10,d0
  457.     beq.b end1        ; "LF" nicht zurückstellen
  458.     bsr.b Unget
  459. end1    movem.l (a7)+,d0/d2-d7/a2-a6
  460.     rts
  461.  
  462. OverreadLN:    ; In Stream Zwischenraum überlesen, aber nicht LF
  463.     cmp.b #' ',d0
  464.     beq.b ovl1
  465.     cmp.b #9,d0
  466.     beq.b ovl1
  467.     cmp.b #13,d0
  468.     beq.b ovl1
  469.     rts
  470. ovl1    bsr.b Get
  471.     bra.b OverreadLN
  472.  
  473. Overread:    ; In Stream Zwischenraum überlesen
  474.     bsr.b OverreadLN
  475.     cmp.b #10,d0
  476.     bne ret
  477.     bsr.b Get
  478.     bra.b Overread
  479.  
  480. OverreadFormat:    ; im Formatstring Zwischenraum überlesen, Zeichen nach d1
  481.     move.b (a1)+,d1
  482.     beq.b ovr0
  483.     cmp.b #' ',d1
  484.     beq.b OverreadFormat
  485.     cmp.b #9,d1
  486.     beq.b OverreadFormat
  487.     cmp.b #10,d1
  488.     beq.b OverreadFormat
  489.     cmp.b #13,d1
  490.     beq.b OverreadFormat
  491. ovr0    rts
  492.  
  493. Get:    ; Zeichen nach d0.l und d7 incrementieren, oder -1
  494.     move.l    a0,-(a7)
  495.     beq.b    gtChar        ; a0=0, also sscanf
  496.     jsr    fgetc__P06stream
  497.     move.l    (a7)+,a0
  498.     tst.l    d0
  499.     bmi.b    gt1
  500. gt0    addq.l    #1,d7
  501. gt1    rts
  502. gtChar    addq.l    #4,a7
  503.     moveq    #0,d0
  504.     move.b    (a6)+,d0
  505.     bne.b    gt0
  506.     moveq    #-1,d0
  507.     rts
  508.  
  509. Unget:    ; d0 zurückstellen, falls nicht -1
  510.     tst.l    d0
  511.     bmi.b    ung1
  512.     move.l    a0,-(a7)
  513.     beq.b    ungChar
  514.     move.l    d0,-(a7)
  515.     jsr    ungetc__iP06stream
  516.     addq.l    #4,a7
  517.     move.l    (a7)+,a0
  518.     subq.l    #1,d7
  519. ung1    rts
  520. ungChar    addq.l    #4,a7
  521.     subq.l    #1,a6
  522.     subq.l    #1,d7
  523.     rts
  524.  
  525.     end
  526.