OpenCores
URL https://opencores.org/ocsvn/forwardcom/forwardcom/trunk

Subversion Repositories forwardcom

[/] [forwardcom/] [libraries/] [gets_light.as] - Rev 114

Go to most recent revision | Compare with Previous | Blame | View Log

/****************************  gets_light.as **********************************
* Author:        Agner Fog
* date created:  2021-05-25
* Last modified: 2021-07-20
* Version:       1.11
* Project:       ForwardCom library libc_light.li
* Description:   gets_s: Read a string from standard input until newline
* This version is for small CPUs with limited capabilities
* The following instructions are avoided: mul, div, push, pop, sys_call.
* Input comes directly from input port 8
* Output to stdout goes directly to output port 10
*
* C declaration:
* char *gets_s (char *string, size_t max_length);
*
* This function is defined in the C11 standard
* It will read a string from stdin until a newline or carriage return is 
* encountered or the maximum length is reached.
* The input is echoed to standard output.
* The newline or carriage return is not included in the string. 
* A terminating zero is always inserted at the end of the string.
* If the string length, including the terminating zero, exceeds max_length
* then the superfluous characters are discarded and it keeps reading until
* a newline or carriage return. 
* This version does not raise any exception in case max_length is exceeded,
* but returns a truncated string. 
* A NULL pointer is returned if any of the input parameters are zero.
* The C standard says that reading ends at newline, but Windows versions end
* at carriage return. This version supports both for the sake of compatibility.
*
* Copyright 2021 GNU General Public License http://www.gnu.org/licenses
*****************************************************************************/

// define input and output port numbers
%stdin_port = 8
%stdin_status_port = 9
%stdout_port = 10


code section execute 

_gets_s function public reguse = 3, 0

  // save r2, r3
  int64 sp -= 2*8
  int64 [sp] = r2
  int64 [sp+8] = r3

  // check if parameters are valid
  if (int64 r0 == 0) {jump gets_s_error}         // error: null pointer or zero length
  if (int64 r1 == 0) {jump gets_s_error}         // error: zero length

  int64 r2 = r0                                  // point to current position in output buffer

  // loop until newline or maximum string length
  while (true) {

    // wait for input
    do {
      int16 r3 = input(r3, stdin_status_port)    // check if there is input
    }
    while (int r3 == 0);

    int8 r3 = input(r3, stdin_port)              // read one byte from input    
    int8 output(r3, r3, stdout_port)             // echo input
    if (int r3 == 10) {break}                    // stop at newline
    //if (int r3 == 13) {break}                  // optionally stop at charriage return
    int64 r1--                                   // count down maximum length
    if (int64 r1 <= 0) {continue}                // length limit reached. keep reading until newline
    int8 [r2] = r3                               // store byte as character in output buffer
    int64 r2++                                   // increment string pointer
  }
  int  r3 = 0                                    // insert terminating zero
  int8 [r2] = r3
  gets_s_9:

  // restore r2, r3
  int64 r2 = [sp]
  int64 r3 = [sp+8]
  int64 sp += 2*8
  return

  gets_s_error:
  int r0 = 0
  jump gets_s_9

code end

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.