home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / list / ep-src.ark / FGET.MAC < prev    next >
Text File  |  1988-05-21  |  8KB  |  500 lines

  1.  
  2.     include    BDSYM.EQU
  3.     include    EPDATA
  4.  
  5. IOBUFSIZ    equ    2+2+2+SECSIZ
  6.  
  7.     .comment    `
  8. /* FGET.C - file stack functions for EP        */
  9. /* flnum should be set to 0 before 1st call    */
  10. struct _ebuf {
  11.     int _fd;
  12.     int _nleft;
  13.     char *_nextp;
  14.     char _buff[SECSIZ];
  15. /*    char _flags;*/
  16. };
  17.  
  18. struct _ebuf fl[8];
  19. int flnum;
  20.  
  21. fopen(filename)
  22. char *filename;
  23. {    struct _ebuf *iobuf;
  24.  
  25.     iobuf = fl[flnum];
  26.  
  27.     if ((iobuf -> _fd = open(filename,0))<0) return ERROR;
  28.     iobuf -> _nleft = 0;
  29. /*    iobuf -> _flags = _READ;*/
  30.     flnum++;
  31.     return iobuf -> _fd;
  32. }
  33.  
  34.             `
  35.  
  36. fopen::
  37.     pop    d
  38.     pop    h
  39.     push    h
  40.     push    d
  41.  
  42.  
  43. ;unlike C version, open the file first, so don't have to save *filename
  44.     lxi    d,0
  45.     push    d
  46.     push    h
  47.     call    open##
  48.     pop    d
  49.     pop    d
  50. ;check for error
  51.     mov    a,h
  52.     ora    a
  53.     rm    ;can assume HL = -1 if error
  54. ;ok, so save FD
  55.     push    h
  56.  
  57. ;    iobuf = fl[flnum];
  58.     lhld    _flnum
  59.  
  60.     push    h
  61.     mov    a,l
  62.     cpi    8
  63.     cnc    eperror##
  64.     pop    h
  65.  
  66.     lxi    d,IOBUFSIZ    ;86H
  67.     call    usmul
  68.     lxi    d,fl
  69.     dad    d
  70.     shld    _iob
  71.  
  72. ;
  73. ;    if ((iobuf -> _fd = open(filename,0))<0) return ERROR;
  74.  
  75. ;already open -- stow the FD
  76.     pop    d
  77.     mov    m,e
  78.     inx    h
  79.     mov    m,d
  80.  
  81. ;    iobuf -> _nleft = 0;
  82.     inx    h
  83.     xra    a
  84.     mov    m,a
  85.     inx    h
  86.     mov    m,a
  87.  
  88. ;    flnum++;
  89. ;now treat as byte var.
  90.     lxi    h,_flnum
  91.     inr    m
  92.  
  93. ;    return iobuf -> _fd;
  94. ;DE still has FD
  95. ;}
  96.     xchg
  97.     ret
  98.  
  99. _iob:    dw    0
  100. _flnum:    dw    0
  101.  
  102.     .comment    `
  103.  
  104. getc()
  105. {    struct _ebuf *iobuf;
  106.     char c;
  107.  
  108.   while (flnum>0)
  109.   {
  110.     iobuf = fl[flnum-1];
  111.  
  112.     if (!iobuf->_nleft--)        /* if buffer empty, fill it up first */
  113.      {
  114.         if (read(iobuf -> _fd, iobuf -> _buff, 1) <= 0)
  115.         {    fabort(iobuf -> _fd);
  116.             flnum--;
  117.             continue;
  118.         }
  119.         iobuf -> _nleft = SECSIZ - 1;
  120.         iobuf -> _nextp = iobuf -> _buff;
  121.      }
  122.     if ((c = *iobuf->_nextp++) != CPMEOF) return c;
  123.         else flnum--;
  124.   }
  125.   return EOF;
  126. }
  127.  
  128.             `
  129.  
  130.  
  131.  
  132. getc::
  133.  
  134. ;  while (flnum>0)
  135. ;  {
  136.  
  137.  
  138. .ge1:
  139.     lxi    h,-1    ;for error ret
  140.     lda    _flnum
  141.     ora    a
  142.     rz
  143.  
  144. ;    iobuf = fl[flnum-1];
  145. ;assume current value in _iob is valid
  146.  
  147. ;
  148. ;    if (!iobuf->_nleft--)        /* if buffer empty, fill it up first */
  149.  
  150.     lhld    _iob
  151.  
  152.     inx    h    ;past _fd
  153.     inx    h
  154.     mov    e,m    ;load _nleft
  155.     inx    h
  156.     mov    d,m
  157. ;DE = *_nleft and HL = ->_nleft + 1
  158. ;check here for none
  159.     mov    a,d
  160.     ora    e
  161.     jnz    .ge3
  162. ;*_nleft now updated at .ge3
  163.  
  164.  
  165. ;     {
  166. ;        if (read(iobuf -> _fd, iobuf -> _buff, 1) <= 0)
  167.     lxi    d,1
  168.     push    d
  169.  
  170. ;    lhld    _iob
  171. ;    lxi    d,6
  172. ;    dad    d
  173.     inx    h    ;past high byte of _nleft
  174.     inx    h    ;past _nextp
  175.     inx    h
  176.     push    h    ;this is _buff
  177.  
  178.     lhld    _iob
  179.     mov    e,m    ;load _fd
  180.     inx    h
  181.     mov    d,m
  182.     push    d
  183.  
  184.     call    read##
  185.     pop    d
  186.     pop    d
  187.     pop    d
  188.  
  189. ;HL = 0 for eof? go read embedding file
  190. ;HL = ERROR? same (but this is not right)
  191.     dcx    h
  192.     mov    a,h
  193.     ora    a
  194. ;if ok, go update pointers and return the character
  195.     jp    .ge2
  196.  
  197. ;        {    fabort(iobuf -> _fd);
  198. ;to here when can't read any more chars, or get CPMEOF
  199. .ge4:
  200.     lhld    _iob
  201. ;    mov    d,m
  202. ;    inx    h
  203. ;    mov    e,m
  204. ;    push    d
  205.     mov    a,m
  206.     call    fabort##
  207. ;    pop    d
  208. ;            flnum--;
  209.     lxi    h,_flnum
  210.     dcr    m
  211.  
  212. ;also update _iob
  213.     lhld    _iob
  214.     lxi    d,-IOBUFSIZ
  215.     dad    d
  216.     shld    _iob
  217. ;            continue;
  218. ;        }
  219.     jmp    .ge1
  220.  
  221. ;        iobuf -> _nleft = SECSIZ - 1;
  222. .ge2:    lhld    _iob
  223.  
  224.     inx    h
  225.     inx    h
  226.     mvi    m,SECSIZ - 1
  227.     inx    h
  228.     mvi    m,0
  229.  
  230. ;        iobuf -> _nextp = iobuf -> _buff;
  231. ;     }
  232.     inx    h
  233. ;HL = ->_nextp
  234.     mov    d,h
  235.     mov    e,l
  236.     inx    d
  237.     inx    d
  238. ;DE = ->_buff
  239.  
  240. ;we may as well go ahead and load the character
  241.     ldax    d
  242.     inx    d
  243.  
  244.     mov    m,e
  245.     inx    h
  246.     mov    m,d
  247.  
  248. ;go directly to check for CPMEOF with char in A
  249.     jmp    .ge3x
  250.  
  251. ;    if ((c = *iobuf->_nextp++) != CPMEOF) return c;
  252. .ge3:
  253. ;now DE = *_nleft and HL = ->_nleft + 1
  254.  
  255. ;decr *_nleft
  256.     dcx    d
  257. ;and store
  258.     mov    m,d
  259.     dcx    h
  260.     mov    m,e
  261.  
  262. ;move pointer to _nextp and load
  263.     inx    h
  264.     inx    h
  265.     mov    e,m
  266.     inx    h
  267.     mov    d,m
  268. ;get char at _nextp
  269.     ldax    d
  270. ;incr *_nextp
  271.     inx    d
  272. ;and store back
  273.     mov    m,d
  274.     dcx    h
  275.     mov    m,e
  276. .ge3x:
  277.     cpi    1AH
  278.     jz    .ge4
  279.  
  280.     mov    l,a
  281.     mvi    h,0
  282.     ret
  283. ;        else flnum--;
  284. ;  }
  285. ;.ge4:    cf. above
  286.  
  287.  
  288.     .comment    `
  289.  
  290. /****************************************************************/
  291. /* Modified version of standard library function 'fgets'.    */
  292. /*   (Needed to prevent overflow when dealing with WordStar    */
  293. /*    document files, since b7 of CR or LF may be set, and    */
  294. /*    this conceals the end of line from regular fgets.)    */
  295. /****************************************************************/
  296. char *fgets(s)
  297. char *s;
  298. {    int count, c;
  299.     char *cptr;
  300.  
  301.     count = MAXLINE - 2;
  302.     cptr = s;
  303.     if ( (c = getc()) == EOF ) return NULL;
  304. /* This way, the 8A page break is effaced.  Change this if need it. */
  305.     do
  306.     {    if (c == SOFTSP) continue;
  307.         if ((*cptr++ = (c & 0x7F))  == '\n')
  308.         {    if (cptr>s+1 &&  *(cptr-2) == '\r')
  309.                 *(--cptr - 1) = '\n';
  310.               break;
  311.         }
  312.     } while (count-- && (c=getc()) != EOF );
  313.  
  314.     /*if (c == CPMEOF) ungetc(c,iobuf);     push back control-Z */
  315.  
  316. /* right-trim blanks and tabs    */
  317.     while (cptr>s+1 && ((c = *(cptr-2)) == ' ') || c == '\t')
  318.         *(--cptr - 1) = '\n';
  319.  
  320.     *cptr = '\0';
  321.  
  322.     return s;
  323. }
  324.  
  325.             `
  326.  
  327. fgets::
  328.     pop    d
  329.     pop    h
  330.     push    h
  331.     push    d
  332.  
  333.     push    b
  334. ;C holds c
  335. ;B holds the last c gotten, or 0 if none
  336.     mvi    b,0    ;no last c, so far
  337.  
  338.     shld    _fgs
  339.     shld    _cptr    ;cf. below
  340. ;    count = MAXLINE - 2;
  341.  
  342.     lxi    h,MAXLINE-2
  343.     shld    _count
  344.  
  345. ;    cptr = s;
  346.  
  347. ;    if ( (c = getc()) == EOF ) return NULL;
  348.     call    getc
  349.     mov    c,l
  350.  
  351.     inx    h
  352.     mov    a,h
  353.     ora    l
  354.     jnz    .fg1
  355. ;(HL = NULL = 0)
  356.     pop    b
  357.     ret
  358.  
  359. ;/* This way, the 8A page break is effaced.  Change this if need it. */
  360. ;    do
  361. ;    {    if (c == SOFTSP) continue;
  362. .fg1:
  363.     mov    a,c
  364.     cpi    SOFTSP
  365.     jz    .fg4
  366.  
  367. ;        if ((*cptr++ = (c & 0x7F))  == '\n')
  368. .fg2:
  369.     ani    7fh
  370.     lhld    _cptr
  371.     mov    m,a
  372.     inx    h
  373.     shld    _cptr
  374.  
  375.     cpi    0ah
  376.     jnz    .fg4
  377. ;        {    if (cptr>s+1 &&  *(cptr-2) == '\r')
  378. ;If this is the first time through the loop,
  379. ; cptr = s+1, but then the last c in B will be zero.
  380. ;Also, *(cptr-2) is the last c, so the above conditions
  381. ; are met iff B = 0dh.
  382.     mov    a,b
  383.     cpi    0dh
  384.     jnz    .fg5
  385.  
  386. ;    lhld    _cptr
  387. ;    xchg
  388. ;    lhld    _fgs
  389. ;    inx    h
  390. ;    call    agbu
  391. ;    jnc    .fg3 (== .fg5)
  392. ;
  393. ;    lhld    _cptr
  394. ;    dcx    h
  395. ;    dcx    h
  396. ;    mov    a,m
  397. ;    cpi    0DH
  398. ;    jnz    .fg3
  399.  
  400. ;                *(--cptr - 1) = '\n';
  401. ;              break;
  402. ;        }
  403.  
  404. ;    lhld    _cptr
  405. ;here we got a CR-LF
  406.  
  407. ;point to the LF
  408.     dcx    h
  409. ;now this is the end of the string
  410.     shld    _cptr
  411. ;point to the CR
  412.     dcx    h
  413. ;write a LF over it
  414.     mvi    m,0ah
  415.  
  416.     jmp    .fg5
  417.  
  418. ;    } while (count-- && (c=getc()) != EOF );
  419. .fg4:
  420.     lhld    _count
  421.     mov    a,h
  422.     ora    l
  423.     dcx    h
  424.     shld    _count
  425. ;    jz    .fg5
  426. ;(don't try to trim over long lines)
  427.     jz    .fg7
  428.  
  429. ;last c = old c
  430.     mov    b,c
  431.  
  432.     call    getc
  433.     mov    c,l
  434.  
  435.     inx    h    ;check for eof or error
  436.     mov    a,h
  437.     ora    l
  438.     jnz    .fg1
  439. ;To get here, the file must not have been terminated with CR-LF.
  440. ;This is not in the c-version, but the best thing seems to add a NL:
  441.     lhld    _cptr
  442.     mvi    m,0ah
  443.     inx    h
  444.     shld    _cptr
  445. ;
  446. ;/* right-trim blanks and tabs    */
  447. ;    while (cptr>s+1 && ((c = *(cptr-2)) == ' ') || c == '\t')
  448. ;        *(--cptr - 1) = '\n';
  449. ;
  450.  
  451. .fg5:
  452. ;We depart from the c-version:
  453. ;
  454. ;First, mark before the beginning of the string with a nul,
  455. ; saving the byte here
  456.     lhld    _fgs
  457.     dcx    h
  458.     mov    c,m
  459.     mvi    m,0
  460.     xchg
  461. ;Then starting at the last c stored, which was a LF, at cptr-1, ...
  462.     lhld    _cptr
  463.     dcx    h
  464. .fgtrim:
  465. ;go back until preceding is not blank or tab
  466.     dcx    h
  467.     mov    a,m
  468.     cpi    ' '
  469.     jz    .fgtrim
  470.     cpi    9
  471.     jz    .fgtrim
  472. ;write LF over last blank or tab char, or over LF itself if there were none
  473.     inx    h
  474.     mvi    m,0ah
  475. ;and cptr points after the LF
  476.     inx    h
  477.     shld    _cptr
  478. ;Restore the byte before the string
  479.     xchg
  480.     mov    m,c
  481.  
  482.  
  483. ;    *cptr = '\0';
  484. .fg7:
  485.     lhld    _cptr
  486.     mvi    m,0
  487. ;
  488. ;    return s;
  489.     lhld    _fgs
  490. ;}
  491. .fg8:
  492.     pop    b
  493.     ret
  494.  
  495. _fgs:        dw    0
  496. _count:        dw    0
  497. _cptr:        dw    0
  498.  
  499.     end
  500.