File:  [Coherent Logic Development] / freem / src / ssvn.c
Revision 1.3: download - view: text, annotated - select for diffs
Sun Mar 9 19:50:47 2025 UTC (3 weeks, 2 days ago) by snw
Branches: MAIN
CVS tags: v0-62-3, v0-62-2, v0-62-1, v0-62-0, HEAD
Second phase of REUSE compliance and header reformat

/*
 *   $Id: ssvn.c,v 1.3 2025/03/09 19:50:47 snw Exp $
 *    structured system variable support
 *
 *  
 *   Author: Serena Willis <snw@coherent-logic.com>
 *    Copyright (C) 1998 MUG Deutschland
 *    Copyright (C) 2020, 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: ssvn.c,v $
 *   Revision 1.3  2025/03/09 19:50:47  snw
 *   Second phase of REUSE compliance and header reformat
 *
 *
 * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
 * SPDX-License-Identifier: AGPL-3.0-or-later
 **/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#if !defined(__OpenBSD__) && !defined(__FreeBSD__)
# include <sys/timeb.h>
#endif
#include "mpsdef.h"
#include "freem.h"
#include "mref.h"
#include "mdebug.h"

#ifdef USE_SYS_TIME_H
# include <sys/time.h>
#endif

typedef struct ssvn_lut {
    const char *input_name;
    const char *canonical_name;
} ssvn_lut;

 ssvn_lut ssv_tab[] = {
    {"^$C", "^$CHARACTER"},
    {"^$CHARACTER", "^$CHARACTER"},
    {"^$D", "^$DEVICE"},
    {"^$DEVICE", "^$DEVICE"},
    {"^$DI", "^$DISPLAY"},
    {"^$DISPLAY", "^$DISPLAY"},
    {"^$E", "^$EVENT"},
    {"^$EVENT", "^$EVENT"},
    {"^$G", "^$GLOBAL"},
    {"^$GLOBAL", "^$GLOBAL"},
    {"^$J", "^$JOB"},
    {"^$JOB", "^$JOB"},
    {"^$LI","^$LIBRARY"},
    {"^$LIBRARY","^$LIBRARY"},
    {"^$L", "^$LOCK"},
    {"^$LOCK", "^$LOCK"},
    {"^$O", "^$OBJECT"},
    {"^$OBJECT", "^$OBJECT"},
    {"^$R", "^$ROUTINE"},
    {"^$ROUTINE", "^$ROUTINE"},
    {"^$S", "^$SYSTEM"},
    {"^$SYSTEM", "^$SYSTEM"},
    {"^$W", "^$WINDOW"},
    {"^$WINDOW", "^$WINDOW"},
    {"^$ZF", "^$ZFILE"},
    {"^$ZFILE", "^$ZFILE"},
    {"^$ZFR", "^$ZFREEM"},
    {"^$ZFREEM", "^$ZFREEM"},
    {"^$ZD", "^$ZDIRECTORY"},
    {"^$ZDIRECTORY", "^$ZDIRECTORY"},
    {"^$ZO", "^$ZOS"},
    {"^$ZOS", "^$ZOS"},
    {"^$ZP", "^$ZPROCESS"},
    {"^$ZPROCESS", "^$ZPROCESS"},
    {"^$ZR", "^$ZRPI"},
    {"^$ZRPI", "^$ZRPI"},
    {NULL, NULL}
};


void ssvn (short action, char *key, char *data);
void ssvn_normalize_key (char *key);

/* structured system variable management */
/* set_sym      get_sym   */
/* kill_sym     $data     */
/* kill_all     $fra_order    */
/* killexcl     $fra_query    */
/* new_sym                */
/* new_all      getinc    */
/* newexcl                */
/* killone      m_alias   */
/* merge_sym    zdata     */
void ssvn (short action, char *key, char *data)
{
    int i, j;
    char ch;
    char ptmp[256];

    if ((rtn_dialect () == D_M77) ||
        (rtn_dialect () == D_M84) ||
        (rtn_dialect () == D_M90)) {
        merr_raise (NOSTAND);
        return;
    }
    
    i = 1;
    j = 2;
    
    while ((ch = key[j]) != EOL) {

        if (ch >= 'a' && ch <= 'z') ch -= 32;
        if (ch == DELIM) break;
	
        ptmp[i++] = ch;
        j++;

    }
    
    ptmp[0] = SP;
    ptmp[i++] = SP;
    ptmp[i] = EOL;

    ssvn_normalize_key (key);

    if (dbg_enable_watch && (action == set_sym)) dbg_fire_watch (key);

    if (merr () > OK) return;


    if ((ptmp[1] != 'Z') && (ptmp[1] != 'Y')) {

        if (find (" C CHARACTER D DEVICE DI DISPLAY E EVENT G GLOBAL J JOB LI LIBRARY L LOCK O OBJECT P R ROUTINE S SYSTEM W WINDOW ", ptmp) == FALSE) {
            merr_raise (M60);
            return;
        }

        switch (ptmp[1]) {

            case 'C':			/* ^$CHARACTER ssvn */
                ssvn_character (action, key, data);
                break;
			
            case 'D':			/* ^$DEVICE and ^$DISPLAY ssvns */
                switch(ptmp[2]) {
            
                    case 'E':   /* ^$DEVICE */
                        ssvn_device (action, key, data);
                        break;
            
                    case 'I':   /* ^$DISPLAY */
                        ssvn_display (action, key, data);
                        break;
            
                    default:
                        merr_raise (INVREF);
                        break;
                }  

                break;              			 
            
            case 'E':                   /* ^$EVENT ssvn */
                ssvn_event (action, key, data);
                break;
			
            case 'G':		        /* ^$GLOBAL ssvn */
                ssvn_global (action, key, data);
                break;
			
            case 'J':			/* ^$JOB ssvn */	  
                ssvn_job (action, key, data);
                break;
			
            case 'L':			/* ^$LIBRARY/^$LOCK ssvns */
                if (ptmp[2] == 'I') {
                    ssvn_library (action, key, data);
                }
                else {
                    ssvn_lock (action, key, data);
                }
                break;
                
            case 'O':
                ssvn_object (action, key, data);
                break;
                
            case 'R':			/* ^$ROUTINE ssvn */
                ssvn_routine (action, key, data);
                break;
			
            case 'S':			/* ^$SYSTEM ssvn */
                ssvn_system (action, key, data);
                break;
			
            case 'W':			/* ^$WINDOW ssvn */
                ssvn_window (action, key, data);
                break;
			
            default:
                merr_raise (INVREF);
                break;
        }
    } 
    else {				/* implementation-specific ssvns */
        ssvn_z (action, key, data);
        return;
    }

    return;
}

/* convert SSVN names to canonical form (all caps, full-length name) */
void ssvn_normalize_key (char *key)
{
    freem_ref_t *ref;
    char *new_key;
    ssvn_lut *p;
    register int i;

    
    ref = malloc (sizeof (freem_ref_t));
    NULLPTRCHK(ref,"ssvn_normalize_key");
    
    mref_init (ref, MREF_RT_SSVN, "");
    internal_to_mref (ref, key);

    for (i = 0; i < strlen (ref->name); i++) {
        if (ref->name[i] >= 'a' && ref->name[i] <= 'z') ref->name[i] -= 32;
    }


    for (p = ssv_tab; p->input_name != NULL; ++p) {

        if (strcmp (ref->name, p->input_name) == 0) {
            
            strcpy (ref->name, p->canonical_name);

            new_key = mref_to_internal (ref);
            stcpy (key, new_key);

            free (ref);
            free (new_key);

            merr_clear ();
            return;

        }

    }

    merr_raise (M60);

    free (ref);
    
    return;

}

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