Annotation of freem/src/mref.c, revision 1.6

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

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