File:  [Coherent Logic Development] / freem / src / mref.c
Revision 1.7: download - view: text, annotated - select for diffs
Thu Apr 10 01:24:38 2025 UTC (3 months, 3 weeks ago) by snw
Branches: MAIN
CVS tags: HEAD
Remove C++ style comments

    1: /*
    2:  *   $Id: mref.c,v 1.7 2025/04/10 01:24:38 snw Exp $
    3:  *    supporting functions for handling freem_ref_t structures
    4:  *
    5:  *  
    6:  *   Author: Serena Willis <snw@coherent-logic.com>
    7:  *    Copyright (C) 1998 MUG Deutschland
    8:  *    Copyright (C) 2020, 2025 Coherent Logic Development LLC
    9:  *
   10:  *
   11:  *   This file is part of FreeM.
   12:  *
   13:  *   FreeM is free software: you can redistribute it and/or modify
   14:  *   it under the terms of the GNU Affero Public License as published by
   15:  *   the Free Software Foundation, either version 3 of the License, or
   16:  *   (at your option) any later version.
   17:  *
   18:  *   FreeM is distributed in the hope that it will be useful,
   19:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   20:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21:  *   GNU Affero Public License for more details.
   22:  *
   23:  *   You should have received a copy of the GNU Affero Public License
   24:  *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
   25:  *
   26:  *   $Log: mref.c,v $
   27:  *   Revision 1.7  2025/04/10 01:24:38  snw
   28:  *   Remove C++ style comments
   29:  *
   30:  *   Revision 1.6  2025/04/09 15:16:50  snw
   31:  *   Fix buffer overruns in mref_to_external and ssvn.c
   32:  *
   33:  *   Revision 1.5  2025/03/22 18:43:54  snw
   34:  *   Make STRLEN 255 chars and add BIGSTR macro for larger buffers
   35:  *
   36:  *   Revision 1.4  2025/03/09 19:50:47  snw
   37:  *   Second phase of REUSE compliance and header reformat
   38:  *
   39:  *
   40:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
   41:  * SPDX-License-Identifier: AGPL-3.0-or-later
   42:  **/
   43: 
   44: #include <stdio.h>
   45: #include <stdlib.h>
   46: #include <string.h>
   47: #include <mpsdef0.h>
   48: 
   49: #include "freem.h"
   50: 
   51: #define MREF_CHECK(ref,index,type) if (ref->status != MREF_ST_INIT || index > 255 || index < 0) return (type) NULL
   52: #define MREF_CHECK_EXIT(ref,index,type) if (ref->status != MREF_ST_INIT || index > 255 || index < 0) exit (type) NULL
   53: 
   54: extern short g_numeric (char *str);
   55: 
   56: freem_ref_t *mref_init (freem_ref_t *ref, short ref_type, char *name) 
   57: {
   58:     if (strlen (name) > 255) {
   59:         ref->status = MREF_ST_ERR;
   60:         return ref;
   61:     }
   62: 
   63:     ref->reftype = ref_type;
   64:     ref->status = MREF_ST_INIT;
   65:     strncpy (ref->name, name, 255);
   66:     ref->subscript_count = 0;
   67: 
   68:     return ref;
   69: }
   70: 
   71: char *mref_get_name (freem_ref_t *ref)
   72: {
   73:     MREF_CHECK (ref, 0, char *);
   74: 
   75:     return ref->name;
   76: }
   77: 
   78: char *mref_get_subscript (freem_ref_t *ref, int index)
   79: {
   80:     /* ref must be initialized, and index within range */
   81:     MREF_CHECK (ref, index, char *);
   82:     
   83:     return ref->subscripts[index];
   84: }
   85: 
   86: freem_ref_t *mref_set_subscript (freem_ref_t *ref, int index, char *value)
   87: {
   88:     MREF_CHECK (ref, index, freem_ref_t *);
   89: 
   90:     if (ref->subscript_count == 0 && index == 0) ref->subscript_count = 1;
   91: 
   92:     if (ref->subscript_count < (index + 1)) {
   93:         ref->subscript_count = index + 1;
   94:     }
   95: 
   96:     strncpy (ref->subscripts[index], value, 255);
   97: 
   98:     return ref;
   99: }
  100: 
  101: void mref_to_internal_prealloc (char *res, freem_ref_t *ref)
  102: {
  103:     register int i;
  104: 
  105: /*    MREF_CHECK (ref, 0, char *); */
  106: 
  107:     strncpy (res, ref->name, STRLEN - 1);
  108:     
  109:     for (i = 0; i < ref->subscript_count; i++) {
  110:         strncat (res, "\202", STRLEN - 1);
  111:         strncat (res, ref->subscripts[i], STRLEN - 1);
  112:     }
  113: 
  114:     strncat (res, "\201", STRLEN - 1);
  115:     stcnv_c2m (res);   
  116: 
  117: }
  118: 
  119: char *mref_to_internal (freem_ref_t *ref)
  120: {
  121: 
  122:     char *tmp = (char *) malloc (STRLEN * sizeof(char));
  123:     register int i;
  124: 
  125:     MREF_CHECK (ref, 0, char *);
  126: 
  127:     strncpy (tmp, ref->name, STRLEN - 1);
  128:     
  129:     for (i = 0; i < ref->subscript_count; i++) {
  130:         strncat (tmp, "\202", STRLEN - 1);
  131:         strncat (tmp, ref->subscripts[i], STRLEN - 1);
  132:     }
  133: 
  134:     strncat (tmp, "\201", STRLEN - 1);
  135:     stcnv_c2m (tmp);
  136: 
  137:     return tmp;
  138: }
  139: 
  140: /* convert a DELIM-delimited, EOL-terminated key to a freem_ref_t* */
  141: freem_ref_t *internal_to_mref (freem_ref_t *ref, char *key)
  142: {
  143:     register int i;
  144:     register int j;
  145:     char *ptr = key;
  146:     char ch;
  147:     char *nam = (char *) malloc (STRLEN * sizeof(char));
  148:     char *tmp = (char *) malloc (STRLEN * sizeof(char));
  149: 
  150:     MREF_CHECK (ref, 0, freem_ref_t *);
  151: 
  152:     /* shunt the name into ref->name */
  153:     i = 0;
  154:     while ((ch = *(ptr++)) != DELIM && ch != EOL) {
  155:         nam[i++] = ch;
  156:     }
  157: 
  158:     nam[i] = '\0';
  159: 
  160:     if (nam[0] == '^') {
  161:         
  162:         if (nam[1] == '$') {
  163:             ref->reftype = MREF_RT_SSVN;
  164:         }
  165:         else {
  166:             ref->reftype = MREF_RT_GLOBAL;
  167:         }
  168: 
  169:     }
  170:     else {
  171:         ref->reftype = MREF_RT_LOCAL;
  172:     }
  173: 
  174:     strncpy (ref->name, nam, STRLEN);
  175: 
  176:     /* if no subscripts, return the ref */
  177:     if (*(ptr - 1) == EOL) {
  178:         ref->subscript_count = 0;
  179: 
  180:         free (nam);
  181:         free (tmp);
  182: 
  183:         return ref;
  184:     }
  185: 
  186: 
  187:     /* grab the subscripts */
  188:     i = 0;
  189:     j = 0;
  190:     while ((ch = *(ptr++)) != EOL) {
  191: 
  192:         switch (ch) {
  193: 
  194:             case '\001':                
  195:                 break;
  196:             case DELIM:
  197:                 
  198:                 tmp[j] = '\0';
  199: 
  200:                 mref_set_subscript (ref, i++, tmp);
  201:                 ref->subscript_count++;
  202:                 
  203:                 j = 0;
  204:                 tmp[j] = '\0';
  205:                 
  206:                 break;
  207: 
  208: 
  209:             default:
  210:                 tmp[j++] = ch;
  211: 
  212:         }
  213: 
  214:     }
  215: 
  216:     tmp[j] = '\0';
  217: 
  218:     /* grab the last one */
  219:     mref_set_subscript (ref, i, tmp);
  220:     
  221:     free (nam);
  222:     free (tmp);
  223: 
  224:     return ref;
  225: 
  226: }
  227: 
  228: void mref_to_external (freem_ref_t *ref, char *buf)
  229: {
  230:     register int i;
  231:     register int j;
  232:     short is_numeric = FALSE;
  233:     short is_ref = FALSE;
  234:     char *t_buf = (char *) malloc (STRLEN * sizeof (char));
  235:     NULLPTRCHK(t_buf,"mref_to_external");
  236:     
  237:     strcpy (buf, ref->name);
  238: 
  239:     if (ref->subscript_count) {
  240: 
  241:         strcat (buf, "(");  
  242: 
  243: 
  244:         for (i = 0; i < ref->subscript_count; i++) {
  245: 
  246:             if (ref->subscripts[i][0] == '.') {
  247:                 is_ref = TRUE;
  248:             }
  249:             else {
  250:                 is_ref = FALSE;
  251:             }
  252: 
  253:             strcpy (t_buf, ref->subscripts[i]);
  254: 
  255:             for (j = 0; j < strlen (t_buf); j++) {
  256:                 if (t_buf[j] == '\001') t_buf[j] = '\201';
  257:             }
  258: 
  259:             stcnv_c2m (t_buf);
  260: 
  261:             is_numeric = numeric (t_buf);
  262: 
  263:             
  264:             if (!is_numeric && !is_ref) strcat (buf, "\"");
  265: 
  266:             for (j = 0; j < strlen (ref->subscripts[i]); j++) {
  267:                 if (ref->subscripts[i][j] == '\001') ref->subscripts[i][j] = '\201';
  268:             }
  269:             strcat (buf, ref->subscripts[i]);
  270:             if (!is_numeric && !is_ref) strcat (buf, "\"");
  271: 
  272:             if (i < (ref->subscript_count - 1)) {
  273:                 strcat (buf, ",");
  274:             }
  275: 
  276:         }
  277:         stncnv_m2c (buf, STRLEN);
  278: 
  279:         strcat (buf, ")");
  280: 
  281:     }
  282: 
  283:     free (t_buf);
  284:     return;
  285:     
  286: }
  287: 
  288: /* returns TRUE if b is a descendant of a */
  289: short mref_is_descendant(freem_ref_t *a, freem_ref_t *b)
  290: {    
  291:     register int i;
  292: 
  293:     if (a->subscript_count > b->subscript_count) return FALSE;
  294:     if ((strcmp (a->name, b->name) == 0) && (a->subscript_count == 0)) return TRUE;
  295:     
  296:     
  297:     for (i = 0; i < a->subscript_count; i++) {
  298:         if (strcmp (b->subscripts[i], a->subscripts[i]) != 0 ) {
  299: 
  300:             return FALSE;
  301:         }
  302:     }
  303:     
  304:     return TRUE;    
  305: }

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