File:  [Coherent Logic Development] / freem / src / mref.c
Revision 1.3: download - view: text, annotated - select for diffs
Sun Mar 9 15:20:18 2025 UTC (6 months, 2 weeks ago) by snw
Branches: MAIN
CVS tags: HEAD
Begin formatting overhaul and REUSE compliance

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

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