delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1996/08/21/12:58:52

Message-Id: <199608211637.BAA26832@mars.st.rim.or.jp>
To: djgpp-workers AT delorie DOT com
Subject: CR/LF conversion
Mime-Version: 1.0
Date: Thu, 22 Aug 1996 01:37:27 +0900
From: =?ISO-2022-JP?B?GyRCQEQ7M0JnMnAbKEI=?= /Daisuke Aoyama <jack AT st DOT rim DOT or DOT jp>

There is handling of smart CR/LF conversion and tiny filters.
These code are compatible but not yet complete.
You need to be compiled and replaced with djgpp's object in libc.a

------ read.c ----------------------------------------------------------
#include <libc/stubs.h>
#include <fcntl.h>
#include <io.h>
#include <stddef.h>
#include <unistd.h>
#include <libc/dosio.h>

#define _DEV_STDIN  0x0001
#define _DEV_STDOUT 0x0002
#define _DEV_NUL    0x0004
#define _DEV_CLOCK  0x0008
#define _DEV_RAW    0x0020
#define _DEV_CDEV   0x0080
#define _DEV_IOCTRL 0x4000

#define CPMEOF 0x1a /* Ctrl+Z */

static ssize_t
_read_raw_tty (int handle, void *buffer, size_t count)
{
  return 0;
}

static ssize_t
_read_cooked_tty (int handle, void *buffer, size_t count)
{
  return 0;
}

ssize_t
read (int handle, void *buffer, size_t count)
{
  short devmod;
  ssize_t bytes;

  /* check handle whether valid or not */
  devmod = _get_dev_info (handle);
  if (devmod == -1)
    return -1;

  if (count == 0)
    return 0;

#if 0 /* not supported yet */
  if (devmod & _DEV_CDEV)
    {
      /* character device */
      if (devmod & _DEV_RAW)
	return _read_raw_tty (handle, buffer, count);
      else
	return _read_cooked_tty (handle, buffer, count);
    }
#endif

  if (__file_handle_modes[handle] & O_BINARY)
    {
      bytes = _read (handle, buffer, count);
      if (bytes < 0)
	return -1;
    }
  else
    {
      char *rp, *wp;
      char ch;
      ssize_t n;

      bytes = _read (handle, buffer, count);
      if (bytes < 0)
	return -1;

      rp = wp = buffer;
      n = bytes;
      while (--n >= 0)
	{
	  ch = *rp++;
	  if (ch == CPMEOF)
	    {
	      ++n;
	      (void) lseek (handle, -n, SEEK_CUR);
	      break;
	    }
	  else if (ch == '\r')
	    {
	      if (n > 0)
		{
		  /* peek next character */
		  if (*rp == '\n')
		    {
		      /* if found '\n', delete '\r' */
		      ch = *rp++;
		      --n;
		    }
		}
	      else
		{
		  char tmpch;

		  /* read a character to peek */
		  if (_read (handle, &tmpch, 1) == 1)
		    {
		      if (tmpch == '\n')
			ch = tmpch;
		      else
			(void) lseek (handle, -1, SEEK_CUR);
		    }
		}
	    }
	  *wp++ = ch;
	}
      bytes = wp - (char *) buffer;
    }

  return bytes;
}
------ write.c ---------------------------------------------------------
#include <libc/stubs.h>
#include <fcntl.h>
#include <go32.h>
#include <io.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <libc/dosio.h>
#include <libc/bss.h>

#define _DEV_STDIN  0x0001
#define _DEV_STDOUT 0x0002
#define _DEV_NUL    0x0004
#define _DEV_CLOCK  0x0008
#define _DEV_RAW    0x0020
#define _DEV_CDEV   0x0080
#define _DEV_IOCTRL 0x4000

static char sbuf_internal[64];
static char *sbuf = NULL;
static size_t sbuflen = 0;
static int write_count = -1;

#define _MAYBE_FLUSH()						\
do {								\
  if (nbuf >= sbuflen)						\
    {								\
      ssize_t wbytes;						\
								\
      wbytes = _write (handle, sbuf, nbuf);			\
      if (wbytes < 0)						\
	return -1;						\
      if (wbytes < nbuf)					\
	return bytes - (nbuf - wbytes);				\
								\
      wp = sbuf;						\
      nbuf = 0;							\
    }								\
} while (0)

#define _FLUSH()						\
do {								\
  if (nbuf != 0)						\
    {								\
      ssize_t wbytes;						\
								\
      wbytes = _write (handle, sbuf, nbuf);			\
      if (wbytes < 0)						\
	return -1;						\
      if (wbytes < nbuf)					\
	return bytes - (nbuf - wbytes);				\
								\
    }								\
} while (0)

static ssize_t
_write_raw_tty (int handle, void *buffer, size_t count)
{
  return 0;
}

static ssize_t
_write_cooked_tty (int handle, void *buffer, size_t count)
{
  return 0;
}

ssize_t
write (int handle, const void *buffer, size_t count)
{
  short devmod;
  ssize_t bytes;

  /* check handle whether valid or not */
  devmod = _get_dev_info (handle);
  if (devmod == -1)
    return -1;

  if (count == 0)
    return 0;

#if 0 /* not supported yet */
  if (devmod & _DEV_CDEV)
    {
      /* character device */
      if (devmod & _DEV_RAW)
	return _write_raw_tty (handle, buffer, count);
      else
	return _write_cooked_tty (handle, buffer, count);
    }
#endif

  if (__file_handle_modes[handle] & O_BINARY)
    {
      bytes = _write (handle, buffer, count);
      if (bytes < 0)
	return -1;
    }
  else
    {
      const char *rp;
      char *wp;
      ssize_t n, nbuf;

      /* initialize buffer */
      if (write_count != __bss_count)
	{
	  write_count = __bss_count;
	  sbuflen = _go32_info_block.size_of_transfer_buffer;
	  sbuf = malloc (sbuflen);
	  if (sbuf == NULL)
	    {
	      sbuf = &sbuf_internal[0];
	      sbuflen = sizeof (sbuf_internal);
	    }
	}

      rp = buffer;
      wp = sbuf;
      n = count;
      bytes = 0;
      nbuf = 0;
      while (--n >= 0)
	{
	  if (*rp == '\n')
	    {
	      *wp++ = '\r';
	      nbuf++;
	      _MAYBE_FLUSH ();
	    }

	  *wp++ = *rp++;
	  bytes++;
	  nbuf++;
	  _MAYBE_FLUSH ();
	}
      _FLUSH ();
    }

  return bytes;
}
------ sample: tolf.c --------------------------------------------------
/* tolf.c */

#include <fcntl.h>
#include <io.h>
#include <stdio.h>

#define MAXSIZE 4096

int
main ()
{
  char buf[MAXSIZE];

  setmode (fileno (stdout), O_BINARY);
  while (fgets (buf, MAXSIZE, stdin) != NULL)
    {
      fputs (buf, stdout);
    }

  return 0;
}
------ sample: tocrlf.c ------------------------------------------------
/* tocrlf.c */

#include <stdio.h>

#define MAXSIZE 4096

int
main ()
{
  char buf[MAXSIZE];

  while (fgets (buf, MAXSIZE, stdin) != NULL)
    {
      fputs (buf, stdout);
    }

  return 0;
}
------------------------------------------------------------------------

------
Daisuke Aoyama
jack AT st DOT rim DOT or DOT jp

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019