File:  [Coherent Logic Development] / freem / src / cmd_read.c
Revision 1.4: download - view: text, annotated - select for diffs
Mon Mar 24 04:05:36 2025 UTC (8 days, 20 hours ago) by snw
Branches: MAIN
CVS tags: v0-62-3, HEAD
Replace crlf with frm_crlf to avoid symbol conflict with readline on OS/2

/*
 *   $Id: cmd_read.c,v 1.4 2025/03/24 04:05:36 snw Exp $
 *    Implementation of the READ command
 *
 *  
 *   Author: Serena Willis <snw@coherent-logic.com>
 *    Copyright (C) 1998 MUG Deutschland
 *    Copyright (C) 2023, 2025 Coherent Logic Development LLC
 *
 *
 *   This file is part of FreeM.
 *
 *   FreeM is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   FreeM is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero Public License for more details.
 *
 *   You should have received a copy of the GNU Affero Public License
 *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
 *
 *   $Log: cmd_read.c,v $
 *   Revision 1.4  2025/03/24 04:05:36  snw
 *   Replace crlf with frm_crlf to avoid symbol conflict with readline on OS/2
 *
 *   Revision 1.3  2025/03/09 19:14:24  snw
 *   First phase of REUSE compliance and header reformat
 *
 *
 * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
 * SPDX-License-Identifier: AGPL-3.0-or-later 
 **/

#include <string.h>
#include <stdlib.h>
#include "mpsdef.h"
#include "mcommand.h"
#if !defined(MSDOS)
# include "io_socket.h"
#endif

MRESULT cmd_read(MACTION *ra)
{
    register int i;
    register char ch;
    char vn[255];
    char an[255];
    
    if (io != HOME && devopen[io] != 'r' && devopen[io] != '+' && io < FIRSTSCK) {
        return NOREAD;
    }

read_command:

    switch (*codptr)
    {
        case '!':
            if (frm_crlf[io]) {
                write_m ("\012\201");
            }
            else {
                write_m ("\012\015\201");
            }
                    
            if (*++codptr == '!' || *codptr == '#' || *codptr == '?') goto read_command;

            goto cont_read;

        case '#':
            write_m ("\015\014\201");

            if (*++codptr == '!' || *codptr == '#' || *codptr == '?') goto read_command;
                    
            goto cont_read;
                
        case '?':
            codptr++;
                    
            expr (STRING);
                    
            if (merr ()) return merr ();
                    
            write_t ((short) intexpr (argptr));
                    
            goto cont_read;
                
        case '/':
            codptr++;
                    
            expr (NAME);
            if (merr ()) return merr ();

            write_f (varnam);
                    
            codptr++;
                    
            goto cont_read;
                
        case '"':
            i = 0;
                    
            for (;;) {
                        
                while ((ch = *++codptr) > '"') argptr[i++] = ch;
                        
                /* EOL < "any ASCII character" */
                if (ch == '"' && (ch = *++codptr) != '"') {
                    argptr[i] = EOL;
                    write_m (argptr);

                    goto cont_read;
                }

                if ((argptr[i++] = ch) == EOL) {
                    return QUOTER;
                }
            }
    }

    i = InFieldLen;     /* no length limit */
    InFieldLen = 255;       /* Not necessarily tied to STRLEN */

    if (*codptr == '*') {
        codptr++;
        i = 0;
    }           /* single char read */
            
    if (*codptr == '$') {
        return INVREF;
    }

    expr (NAME);
            
    if (merr ()) return merr ();
            
    stcpy (vn, varnam);
    codptr++;           /* lvn */

    if (i != 0 && *codptr == '#') {           /* length limit */
        codptr++;
            
        expr (STRING);
            
        if ((i = intexpr (argptr)) <= 0) return ARGER;
        if (merr ()) return merr ();
    }

    frm_timeout = (-1L);
    timeoutms = 0;      /* no timeout */

    if (*codptr == ':')
    {           /* timeout */
        int i, ch;

        codptr++;

        expr (STRING);
        numlit (argptr);
                
        if (merr ()) return merr ();
                
        frm_timeout = 0;
        timeoutms = 0;
                
        if (argptr[0] != '-') {
                    
            i = 0;

            for (;;) { /* get integer and fractional part */ 
                        
                if ((ch = argptr[i++]) == EOL) break;

                if (ch == '.') {
                        
                    timeoutms = (argptr[i++] - '0') * 100;
                        
                    if ((ch = argptr[i++]) != EOL) {                        
                        timeoutms += (ch - '0') * 10;
                        
                        if ((ch = argptr[i]) != EOL) {
                            timeoutms += (ch - '0');
                        }

                    }
                    break;
                }
                frm_timeout = frm_timeout * 10 + ch - '0';
            }
        }
    } /* if (*codptr == ':') */

#if 0
    set_io (UNIX);
    printf ("READ: io = %d timeout = %d timeoutms = %d count = %d\n", io, frm_timeout, timeoutms, i);
    set_io (MUMPS);
#endif            

    if (io < FIRSTSCK) {
        /* $IO is not a socket device */
        read_m (argptr, frm_timeout, timeoutms, i);
    }
    else {
        /* $IO _is_ a socket device */
        msck_read (io, argptr, frm_timeout, timeoutms, i);
    }

    if (vn[0] != '^') {
        stcpy (an, argptr);
        symtab (set_sym, vn, an);
    }
    else {
        stcpy (an, argptr);
        if (vn[1] == '$') {
            ssvn (set_sym, vn, an);
        }
        else {
            global (set_sym, vn, an);
        }
    }

    if (merr () != OK) {
        stcpy (varerr, vn);
        return merr ();
    }

cont_read:

    *ra = RA_CONTINUE;
    return OK;
}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>