src/vflibcap.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. vf_cap_init
  2. find_vflibcap
  3. vf_cap_GetParsedClassDefault
  4. vf_cap_GetParsedFontEntry
  5. vf_cap_GetFontEntry
  6. get_entry
  7. get_entry2
  8. syntax_check_entry
  9. parse_entry
  10. get_value_if_variable
  11. get_variable_value
  12. main
  13. VF_CAP_GetEntry
  14. VF_CAP_GetString

   1 /* vflibcap.c - a module for reading a vflibcap file.
   2  *
   3  *  Programmmed by Hirotsugu Kakugawa
   4  *  E-Mail:  h.kakugawa@computer.org
   5  *
   6  *  Edition History
   7  *  18 Nov 1997  for VFlib Version 3.4.  Lisp-like syntax.  
   8  *  10 Jun 1998  Added capability arg types CAPABILITY_STRING_LIST0
   9  *               and CAPABILITY_STRING_LIST1.
  10  *  24 Jun 1998  Changed to read environemnt variable value VFLIBCAP_PARAM_xxx
  11  *               as an s-exp.
  12  *  20 Jan 1999  Changed to vflibcap file searching.
  13  *               
  14  */
  15 
  16 /*
  17  * Copyright (C) 1997-1999 Hirotsugu Kakugawa. 
  18  * All rights reserved.
  19  *
  20  * This file is part of the VFlib Library.  This library is free
  21  * software; you can redistribute it and/or modify it under the terms of
  22  * the GNU Library General Public License as published by the Free
  23  * Software Foundation; either version 2 of the License, or (at your
  24  * option) any later version.  This library is distributed in the hope
  25  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
  26  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  27  * PURPOSE.  See the GNU Library General Public License for more details.
  28  * You should have received a copy of the GNU Library General Public
  29  * License along with this library; if not, write to the Free Software
  30  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  31  */
  32 
  33 
  34 #include  "config.h"
  35 #include  <stdio.h>
  36 #include  <stdlib.h>
  37 #if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
  38 #  include  <string.h>
  39 #else
  40 #  include  <strings.h>
  41 #endif
  42 #ifdef HAVE_UNISTD_H
  43 #  include <unistd.h>
  44 #endif
  45 #include  <ctype.h>
  46 #include  <sys/param.h>
  47 #include  <fcntl.h>
  48 #include  "VFlib-3_6.h"
  49 #include  "VFsys.h"
  50 #include  "vflibcap.h"
  51 #include  "consts.h"
  52 #include  "path.h"
  53 #include  "vflpaths.h"
  54 #include  "params.h"
  55 #include  "str.h"
  56 #include  "sexp.h"
  57 
  58 
  59 Private char* find_vflibcap(char *name);
  60 Private SEXP  get_entry(char *type, char *name, char *desc);
  61 Private SEXP  get_entry2(FILE *fp, char *type, char *top_entry, char *name, 
  62                          char *desc, int depth, int *statp);
  63 Private int   syntax_check_entry(SEXP entry);
  64 
  65 Private int   parse_entry(SEXP entry, CAPABILITY_TABLE ct, char *name,
  66                           SEXP_ALIST, SEXP_ALIST, char *def_type);
  67 Private SEXP  get_value_if_variable(SEXP val, SEXP_ALIST,SEXP_ALIST);
  68 Private SEXP  get_variable_value(char *var, SEXP_ALIST,SEXP_ALIST);
  69 
  70 
  71 Private char  *VFlibcapFile = NULL;
  72 
  73 
  74 Glocal int
  75 vf_cap_init(char *vflibcap_file)
     /* [<][>][^][v][top][bottom][index][help] */
  76 {
  77   char    *s;
  78 
  79   if (vf_dbg_vfcap == 1)
  80     printf(">> Init vflibcap: arg=%s\n", 
  81            (vflibcap_file==NULL) ? "<null>" : vflibcap_file);
  82   
  83   if (VFlibcapFile != NULL){
  84     vf_free(VFlibcapFile);
  85     VFlibcapFile = NULL;
  86   }
  87 
  88   /* If env var VFLIB_VFLIBCAP_PATH is defined, use its value as path name */
  89   if ((s = getenv(VF_ENV_VFLIBCAP_PATH)) != NULL){
  90     if (vf_dbg_vfcap == 1)
  91       printf(">>   Checking vflibcap %s  (%s %s)\n",
  92              s, "given by environment variable", VF_ENV_VFLIBCAP_PATH);
  93     VFlibcapFile = find_vflibcap(s);
  94     if (VFlibcapFile == NULL)
  95       return -1;
  96     goto vflibcap_is_found;
  97   }
  98 
  99   if (vflibcap_file == NULL)
 100     vflibcap_file = VF_DEFAULT_VFLIBCAP_FILE;
 101 
 102   /* Search vflibcap in runtime dir */
 103   if ((VFlibcapFile = find_vflibcap(vflibcap_file)) != NULL)
 104     goto vflibcap_is_found;
 105 
 106   /* not found .. */
 107   if (vf_dbg_vfcap == 1)
 108     printf(">>  Not found\n");
 109   if (vf_error != VF_ERR_NO_MEMORY)
 110     vf_error = VF_ERR_NO_VFLIBCAP;
 111   return -1;
 112 
 113 vflibcap_is_found:
 114   if (vf_dbg_vfcap == 1)
 115     printf(">> Found: %s\n", VFlibcapFile);
 116   return 0;
 117 }
 118 
 119 Private char*
 120 find_vflibcap(char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 121 {
 122   char  *s, *p; 
 123 
 124   /* Check vflibcap file relative to current directory */
 125   if (vf_dbg_vfcap == 1)
 126     printf(">>   Checking vflibcap relative to current dir: %s\n", name);
 127   if (vf_path_file_read_ok(name) == TRUE){
 128     if ((s = vf_strdup(name)) == NULL){
 129       vf_error = VF_ERR_NO_MEMORY;
 130       return NULL;
 131     }
 132     return  s;
 133   }
 134 
 135   /* Next, Check vflibcap file in runtime dir */
 136   if (vf_dbg_vfcap == 1)
 137     printf(">>   Checking vflibcap in runtime dir: %s\n", name);
 138   p = vf_path_find_runtime_file(NULL, name, VF_ENV_VFLIBCAP_DIR);
 139 
 140   return p;
 141 }
 142 
 143 
 144 
 145 Glocal int
 146 vf_cap_GetParsedClassDefault(char *class_name, CAPABILITY_TABLE ct,
     /* [<][>][^][v][top][bottom][index][help] */
 147                              SEXP_ALIST varlist1, SEXP_ALIST varlist2)
 148 {
 149   SEXP  entry;
 150   int   v, i;
 151 
 152   if (ct != NULL){
 153     for (i = 0; ct[i].cap != NULL; i++){
 154       if (ct[i].val != NULL)
 155         *(ct[i].val) = NULL;
 156     }
 157   }
 158 
 159   entry = get_entry(VF_CAPE_VFLIBCAP_CLASS_DEFAULT_DEFINITION,
 160                     class_name, "class default");
 161   if (entry == NULL)
 162     return VFLIBCAP_PARSED_NOT_FOUND;
 163 
 164   v = parse_entry(entry, ct, class_name, varlist1, varlist2,
 165                   VF_CAPE_VFLIBCAP_CLASS_DEFAULT_DEFINITION);
 166 
 167   vf_sexp_free(&entry);
 168 
 169   return v;
 170 }
 171 
 172 Glocal int
 173 vf_cap_GetParsedFontEntry(SEXP entry, char *font_name, 
     /* [<][>][^][v][top][bottom][index][help] */
 174                           CAPABILITY_TABLE ct, 
 175                           SEXP_ALIST varlist1, SEXP_ALIST varlist2)
 176 {
 177   int   v, i;
 178 
 179   if (ct != NULL){
 180     for (i = 0; ct[i].cap != NULL; i++){
 181       if (ct[i].val != NULL)
 182         *(ct[i].val) = NULL;
 183     }
 184   }
 185 
 186   if (entry == NULL)
 187     return -1;
 188 
 189   v = parse_entry(entry, ct, font_name, varlist1, varlist2,
 190                   VF_CAPE_VFLIBCAP_FONT_ENTRY_DEFINITION);
 191 
 192   return v;
 193 }
 194 
 195 Glocal SEXP
 196 vf_cap_GetFontEntry(char *font_name)
     /* [<][>][^][v][top][bottom][index][help] */
 197 {
 198   return get_entry(VF_CAPE_VFLIBCAP_FONT_ENTRY_DEFINITION,
 199                    font_name, "font entry");
 200 }
 201 
 202 
 203 
 204 #define GET_ENTRY_STATUS_OK                  0
 205 #define GET_ENTRY_STATUS_LOOP                1
 206 #define GET_ENTRY_STATUS_NOT_FOUND           2
 207 #define GET_ENTRY_STATUS_NOT_FOUND_NEED_MSG  3
 208 
 209 Private SEXP
 210 get_entry(char *type, char *name, char *desc)
     /* [<][>][^][v][top][bottom][index][help] */
 211 {
 212   int   stat;
 213   SEXP  entry;
 214   FILE  *fp;
 215 
 216   if ((fp = fopen(VFlibcapFile, FOPEN_RD_MODE_TEXT)) == NULL){
 217     vf_error = VF_ERR_NO_VFLIBCAP;
 218     if (vf_dbg_vfcap == 1)
 219       printf(">>Can't read vflibcap file: %s\n", VFlibcapFile);
 220     return NULL;
 221   }
 222 
 223   entry = get_entry2(fp, type, name, name, desc, 0, &stat);
 224 
 225   fclose(fp);
 226 
 227   if (stat == GET_ENTRY_STATUS_OK)
 228     return entry;
 229 
 230   vf_error = VF_ERR_NO_FONT_ENTRY;
 231   return NULL;
 232 }
 233 
 234 Private SEXP
 235 get_entry2(FILE *fp, char *type, char *top_entry, char *name,
     /* [<][>][^][v][top][bottom][index][help] */
 236            char *desc, int depth, int *statp)
 237 {
 238   int   expanded, valid;
 239   SEXP  sexp, mdef, mhead, mtail, mlast, prev, s, next;
 240 
 241   *statp = GET_ENTRY_STATUS_OK;
 242 
 243   if (depth > 16){
 244     /* Nesting is too deep. 
 245        Possibly, the inheritance relation must have a loop. */
 246     fprintf(stderr, "VFlib: nesting of %s is too deep in vflibcap %s.\n",
 247             top_entry, VFlibcapFile);
 248     *statp = GET_ENTRY_STATUS_LOOP;
 249     return NULL; 
 250   }
 251 
 252   rewind(fp);
 253   for (;;){
 254     if ((sexp = vf_sexp_read(fp)) == NULL)
 255       break;
 256     if (   vf_sexp_consp(sexp) 
 257         && vf_sexp_stringp(vf_sexp_car(sexp))
 258         && vf_sexp_consp(vf_sexp_cdr(sexp))
 259         && vf_sexp_stringp(vf_sexp_cadr(sexp))  ){     /* (str str ...) */ 
 260       if ((strcmp(vf_sexp_get_cstring(vf_sexp_car(sexp)), type) == 0)
 261           && (strcmp(vf_sexp_get_cstring(vf_sexp_cadr(sexp)), name) == 0)){
 262         if (vf_dbg_vfcap == 1)
 263           printf (">>Found %s %s\n", desc, name);
 264         break;
 265       }
 266     }
 267     vf_sexp_free(&sexp);
 268   }
 269 
 270   if (sexp == NULL){
 271     if (vf_dbg_vfcap == 1)
 272       printf(">>Can't find %s '%s' in vflibcap %s\n", 
 273              desc, name, VFlibcapFile);
 274     *statp = GET_ENTRY_STATUS_NOT_FOUND_NEED_MSG;
 275     return NULL;
 276   }
 277 
 278   /* inheritance by macros */
 279   for (;;){
 280     expanded = 0;
 281     prev = vf_sexp_cdr(sexp);
 282     s    = vf_sexp_cdr(prev);
 283     while (vf_sexp_consp(s)){
 284       if (vf_sexp_stringp(vf_sexp_car(s))){
 285         mdef = get_entry2(fp, VF_CAPE_VFLIBCAP_MACRO_DEFINITION,
 286                           top_entry, vf_sexp_get_cstring(vf_sexp_car(s)), 
 287                           "macro", depth+1, statp);
 288         if (mdef == NULL){
 289           if (*statp == GET_ENTRY_STATUS_NOT_FOUND_NEED_MSG){
 290             fprintf(stderr, "VFlib: macro '%s' is undefined in vflibcap %s\n",
 291                     vf_sexp_get_cstring(vf_sexp_car(s)), VFlibcapFile);
 292             *statp = GET_ENTRY_STATUS_NOT_FOUND;
 293           }
 294           return NULL;
 295         }
 296         /* expand macro */
 297         mhead = mtail = vf_sexp_cddr(mdef);
 298         while (vf_sexp_consp(vf_sexp_cdr(mtail)))
 299           mtail = vf_sexp_cdr(mtail);
 300         mlast = vf_sexp_cdr(mtail);
 301         next = vf_sexp_cdr(s);
 302         vf_sexp_rplacd(prev, mhead);
 303         vf_sexp_rplacd(mtail, next);
 304         /* release garbage */
 305         vf_sexp_cdr(mdef)->t.cons.cdr = NULL; 
 306         vf_sexp_free(&mdef);
 307         vf_sexp_free(&mlast);
 308         s->t.cons.cdr = NULL;
 309         vf_sexp_free(&s);
 310         expanded = 1;
 311         break;
 312       }
 313       prev = s;
 314       s = vf_sexp_cdr(s);
 315     }
 316     if (expanded == 0)
 317       break;
 318   }    
 319 
 320   valid = syntax_check_entry(sexp);
 321   if (!valid){
 322     fprintf(stderr, "VFlib: Syntax error in vflibcap '%s' for entry '%s'.\n",
 323             VFlibcapFile, name);
 324     *statp = GET_ENTRY_STATUS_NOT_FOUND;    
 325     vf_sexp_free(&sexp);
 326     return NULL;
 327   }
 328       
 329   return sexp;
 330 }
 331 
 332 Private int
 333 syntax_check_entry(SEXP entry)
     /* [<][>][^][v][top][bottom][index][help] */
 334 {
 335   char  *str;
 336 #if 0
 337   SEXP  s, t, u, sa;
 338 #endif
 339 
 340   if (   !vf_sexp_listp(entry)
 341       || (vf_sexp_length(entry) < 2)
 342       || !vf_sexp_stringp(vf_sexp_car(entry))
 343       || !vf_sexp_stringp(vf_sexp_cadr(entry)) )
 344     return FALSE;
 345 
 346   str = vf_sexp_get_cstring(vf_sexp_car(entry));
 347   if (   (strcmp(str, VF_CAPE_VFLIBCAP_FONT_ENTRY_DEFINITION) != 0)
 348       && (strcmp(str, VF_CAPE_VFLIBCAP_CLASS_DEFAULT_DEFINITION) != 0)
 349       && (strcmp(str, VF_CAPE_VFLIBCAP_MACRO_DEFINITION) != 0) )
 350     return FALSE;
 351 
 352 #if 0
 353   for (s = vf_sexp_cddr(entry); vf_sexp_consp(s); s = vf_sexp_cdr(s)){
 354     sa = vf_sexp_car(s);
 355     if (   !vf_sexp_listp(sa)
 356         || !vf_sexp_stringp(vf_sexp_car(sa))
 357         || (vf_sexp_length(sa) < 2)  )
 358       return FALSE;
 359     t = vf_sexp_cdr(sa); 
 360     if (vf_sexp_stringp(vf_sexp_car(t))){
 361       /* all elements must be strings */
 362       for (t = vf_sexp_cdr(t); vf_sexp_consp(t); t = vf_sexp_cdr(t)){
 363         if (!vf_sexp_stringp(vf_sexp_car(t)))
 364           return FALSE;
 365       }
 366     } else {
 367       /* must be an alist */
 368       for ( ; vf_sexp_consp(t); t = vf_sexp_cdr(t)){
 369         if (!vf_sexp_listp(vf_sexp_car(t))
 370             || (vf_sexp_length(vf_sexp_car(t)) <= 1))
 371           return FALSE;
 372         for (u = vf_sexp_car(t); !vf_sexp_null(u); u = vf_sexp_cdr(u)){
 373           if (!vf_sexp_stringp(vf_sexp_car(u)))
 374             return FALSE;
 375         }
 376       }
 377     }
 378   }
 379   if (!vf_sexp_null(s))
 380     return FALSE;
 381 #endif
 382 
 383   return TRUE;
 384 }
 385 
 386 
 387 
 388 Private int
 389 parse_entry(SEXP entry, CAPABILITY_TABLE ct, char *name,
     /* [<][>][^][v][top][bottom][index][help] */
 390             SEXP_ALIST varlist1, SEXP_ALIST varlist2, 
 391             char *def_type)
 392 {
 393   SEXP  sexp, scap = NULL, sval, cap_val, v, vvv;
 394   int   val, f, i;
 395   char  *typename;
 396 
 397   if (vf_dbg_vfcap == 1)
 398     printf(">>  Parsing vflibcap entry: (%s %s ...)\n", def_type, name);
 399 
 400   if (entry == NULL)
 401     return VFLIBCAP_PARSED_OK;
 402 
 403   if (ct == NULL){
 404     if (vf_sexp_length(entry) == 2)
 405       return VFLIBCAP_PARSED_OK;
 406     else if (vf_sexp_length(entry) < 2)
 407       return VFLIBCAP_PARSED_ERROR;
 408     for (sexp = vf_sexp_cddr(entry); 
 409          !vf_sexp_null(sexp); 
 410          sexp = vf_sexp_cdr(sexp)){
 411       scap = vf_sexp_caar(sexp);
 412       fprintf(stderr, "VFlib Warning: %s: %s\n",
 413               "undefined capability in vflibcap",
 414               vf_sexp_get_cstring(scap));
 415     }
 416     return VFLIBCAP_PARSED_ERROR;
 417   }
 418 
 419   if (vf_sexp_length(entry) <= 2)
 420     return VFLIBCAP_PARSED_ERROR;
 421 
 422   val = VFLIBCAP_PARSED_OK;
 423 
 424   /* Check capabilities in a vflibcap entry */
 425   for (sexp = vf_sexp_cddr(entry);
 426        vf_sexp_consp(sexp);
 427        sexp = vf_sexp_cdr(sexp)){
 428     if (!vf_sexp_consp(vf_sexp_car(sexp)))
 429       continue;
 430     scap = vf_sexp_caar(sexp);
 431     sval = vf_sexp_cdar(sexp);
 432     for (i = 0; ct[i].cap != NULL; i++){
 433       if (strcmp(vf_sexp_get_cstring(scap), ct[i].cap) == 0)
 434         break;
 435     }
 436     if (ct[i].cap == NULL){
 437       /* the capability given vflibcap is not defined. */
 438       fprintf(stderr, "VFlib Warning: %s '%s' (%s %s ...)\n",
 439               "Undefined capability in vflibcap",
 440               vf_sexp_get_cstring(scap), def_type, name);
 441     } else {
 442       if ((ct[i].val != NULL) && (*(ct[i].val) != NULL)){
 443         fprintf(stderr, "VFlib Warning: %s '%s' in vflibcap (%s %s ...)\n",
 444                 "multiple definition of a capability",
 445                 vf_sexp_get_cstring(scap), def_type, name);
 446         vf_sexp_free(ct[i].val);
 447         *(ct[i].val) = NULL;
 448       }
 449       /* variable expantion. */
 450       if ((strcmp(VF_CAPE_VFLIB_DEFAULTS, name) == 0)
 451           && (strcmp(ct[i].cap, VF_CAPE_VARIABLE_VALUES) == 0))
 452         v = vf_sexp_copy(sval);
 453       else 
 454         v = get_value_if_variable(sval, varlist1, varlist2);
 455       if (v == NULL)
 456         continue;
 457       /* Check the value type. */
 458       cap_val = NULL;
 459       switch (ct[i].type){
 460       case CAPABILITY_LIST:
 461         typename = "a list";
 462         if (vf_sexp_listp(v))
 463           cap_val = vf_sexp_copy(v);
 464         break;
 465       case CAPABILITY_STRING:
 466         typename = "a string";
 467         if (vf_sexp_listp(v) && (vf_sexp_length(v) == 1) 
 468              && (vf_sexp_stringp(vf_sexp_car(v))))
 469           cap_val = vf_sexp_copy(vf_sexp_car(v));
 470         break;
 471       case CAPABILITY_ALIST:
 472         typename = "an alist";
 473         if (vf_sexp_alistp(v))
 474           cap_val = vf_sexp_copy(v);
 475         break;
 476       case CAPABILITY_VECTOR:
 477         typename = "a vector";
 478         if (vf_sexp_listp(v) && (vf_sexp_length(v) == 2)
 479             && (vf_sexp_stringp(vf_sexp_car(v))) 
 480             && (vf_sexp_stringp(vf_sexp_cadr(v))))
 481           cap_val = vf_sexp_copy(v);
 482         break;
 483       case CAPABILITY_STRING_LIST0:
 484         typename = "a list of strings (including none)";
 485         if ((vf_sexp_listp(v) && (vf_sexp_length(v) >= 0))){
 486           f = 1;
 487           for (vvv = v; vf_sexp_consp(vvv); vvv = vf_sexp_cdr(vvv)){
 488             if (!vf_sexp_stringp(vf_sexp_car(vvv))){
 489               f = 0;
 490               break;
 491             }
 492           }
 493           if (f == 1)
 494             cap_val = vf_sexp_copy(v);
 495         }
 496         break;
 497       case CAPABILITY_STRING_LIST1:
 498         typename = "list of strings (at least one)";
 499         if ((vf_sexp_listp(v) && (vf_sexp_length(v) >= 1))){
 500           f = 1;
 501           for (vvv = v; vf_sexp_consp(vvv); vvv = vf_sexp_cdr(vvv)){
 502             if (!vf_sexp_stringp(vf_sexp_car(vvv))){
 503               f = 0;
 504               break;
 505             }
 506           }
 507           if (f == 1)
 508             cap_val = vf_sexp_copy(v);
 509         }
 510         break;
 511       default:
 512         fprintf(stderr, 
 513                 "VFlib internal error: cannot happen in %s\n",
 514                 "parse_entry()");
 515         abort();
 516         break;
 517       }
 518       vf_sexp_free(&v);
 519       if (cap_val != NULL){ 
 520         if ((strcmp(VF_CAPE_VFLIB_DEFAULTS, name) == 0)
 521             && (strcmp(ct[i].cap, VF_CAPE_VARIABLE_VALUES) == 0)){
 522           (void) vf_params_default(vf_sexp_copy(cap_val));
 523         }
 524         if (ct[i].val != NULL)
 525           *(ct[i].val) = cap_val;
 526         else
 527           vf_sexp_free(&cap_val);
 528       } else {   /* type error */
 529         fprintf(stderr, 
 530                 "VFlib: %s '%s' in vflibcap - %s is expected. (%s %s ...)\n",
 531                 "type mismatch for capability",
 532                 vf_sexp_get_cstring(scap), typename, def_type, name);
 533         val = VFLIBCAP_PARSED_ERROR;
 534       }
 535     }
 536   }
 537 
 538   /* Check if essential capabilities are defined. */
 539   for (i = 0; ct[i].cap != NULL; i++){
 540     if (ct[i].ess != CAPABILITY_ESSENTIAL)
 541       continue;
 542     for (sexp = vf_sexp_cddr(entry); 
 543          !vf_sexp_null(sexp); 
 544          sexp = vf_sexp_cdr(sexp)){
 545       scap = vf_sexp_caar(sexp);
 546       if (strcmp(vf_sexp_get_cstring(scap), ct[i].cap) == 0)
 547         break;
 548     }
 549     if (vf_sexp_null(sexp)){
 550       /* the essential capability is not given in vflibcap entry. */
 551       fprintf(stderr, "VFlib Error: %s '%s' %s: (%s %s ... )\n",
 552               "essential capability", vf_sexp_get_cstring(scap), 
 553               "is not given in vflibcap", def_type, name);
 554       val = VFLIBCAP_PARSED_ERROR;
 555     }
 556   }
 557   
 558   if (vf_dbg_vfcap == 1){
 559     for (i = 0; ct[i].cap != NULL; i++){
 560       if ((ct[i].val != NULL) && (*(ct[i].val) != NULL)){
 561         printf("** %s: ", ct[i].cap);
 562         vf_sexp_pp(*(ct[i].val));
 563       }
 564     }
 565   }
 566 
 567   return val;
 568 }
 569 
 570 
 571 Private SEXP
 572 get_value_if_variable(SEXP val,
     /* [<][>][^][v][top][bottom][index][help] */
 573                       SEXP_ALIST varlist1, SEXP_ALIST varlist2)
 574 {
 575   char  *strval, *varname;
 576 
 577   if (vf_sexp_listp(val) && (vf_sexp_length(val) == 1)
 578       && vf_sexp_stringp(vf_sexp_car(val))
 579       && (strncmp(vf_sexp_get_cstring(vf_sexp_car(val)),
 580                   VF_CAPE_VFLIBCAP_VARIABLE_MARK, 
 581                   strlen(VF_CAPE_VFLIBCAP_VARIABLE_MARK)) == 0) ){
 582     /* variable reference */
 583     strval = vf_sexp_get_cstring(vf_sexp_car(val));
 584     varname = &strval[strlen(VF_CAPE_VFLIBCAP_VARIABLE_MARK)];
 585     val = get_variable_value(varname, varlist1, varlist2);
 586     if ((val != NULL) && (vf_dbg_vfcap == 1)){
 587       printf(">>  vflibcap parameterlization: %s => ", varname);
 588       vf_sexp_pp(val);
 589     }
 590   } else {
 591     val = vf_sexp_copy(val);
 592   }
 593 
 594   return val;
 595 }
 596 
 597 Private SEXP
 598 get_variable_value(char *var, 
     /* [<][>][^][v][top][bottom][index][help] */
 599                    SEXP_ALIST varlist1, SEXP_ALIST varlist2)
 600 {
 601   char  *strval, *envname; 
 602   SEXP  v, as;
 603 
 604   /* check an environment variable */
 605   envname 
 606     = (char*)malloc(strlen(VF_ENV_VFLIBCAP_PARAM_PREFIX) + strlen(var) + 1);
 607   if (envname != NULL){
 608     sprintf(envname, "%s%s", VF_ENV_VFLIBCAP_PARAM_PREFIX, var);
 609     if ((strval = getenv(envname)) != NULL){
 610       v = vf_sexp_read_from_string_stream(strval);
 611       if (vf_dbg_vfcap == 1){
 612         printf(">>  Variable (by env var) '%s' = ", var);
 613         vf_sexp_pp(v);
 614       }
 615       return v;
 616     }
 617   }
 618   vf_free(envname);
 619   
 620   /* check parameters given at class default */
 621   if (varlist1 != NULL){
 622     if ((as = vf_sexp_assoc(var, varlist1)) != NULL){
 623       v = vf_sexp_cdr(as);
 624       if (vf_dbg_vfcap == 1){
 625         printf(">>  Variable (by default value) '%s' = ", var);
 626         vf_sexp_pp(v);
 627       }
 628       return vf_sexp_copy(v);
 629     }
 630   }
 631   if (varlist2 != NULL){
 632     if ((as = vf_sexp_assoc(var, varlist2)) != NULL){
 633       v = vf_sexp_cdr(as);
 634       if (vf_dbg_vfcap == 1){
 635         printf(">>  Variable (by default value) '%s' = ", var);
 636         vf_sexp_pp(v);
 637       }
 638       return vf_sexp_copy(v);
 639     }
 640   }
 641 
 642   /* check parameters given at VF_Init() or at VFlib default in vflibcap */
 643   if ((v = vf_params_lookup(var)) != NULL){
 644     if (vf_dbg_vfcap == 1){
 645       printf(">>  Variable (by VF_Init() or VFlib default) '%s' = ", var);
 646       vf_sexp_pp(v);
 647     }
 648     return v;
 649   }
 650 
 651   fprintf(stderr, "VFlib warning: Undefined variable: '%s'\n", var); 
 652   return NULL;
 653 }
 654 
 655 
 656 
 657 
 658 #ifdef  DEBUG
 659 int vf_error = 0;
 660 int vf_dbg_vfcap = 1; 
 661 int vf_dbg_font_search = 0; 
 662 int vf_dbg_parameters = 0; 
 663 int vf_ccv_autoload = 0; 
 664 
 665 int
 666 main(argc, argv)
     /* [<][>][^][v][top][bottom][index][help] */
 667      int argc;
 668      char **argv;
 669 {
 670 #if 0
 671   int    i;
 672   SEXP   entry, iter;
 673   SEXP   val;
 674 
 675   if (argc < 3){
 676     printf("Usage: ./a.out VFLIBCAP ENTRY [CAP1 CAP2 ...]\n");
 677     exit(1);
 678   }
 679   VF_CAP_Init(argv[1], NULL);
 680   if ((entry = VF_CAP_GetFontEntry(argv[2])) != NULL){
 681     vf_sexp_pp(entry);
 682   } else {
 683     printf("not found\n");
 684   }
 685   for (i = 3; i < argc; i++){
 686       printf("\"%s\": \n", argv[i]);
 687     for (iter = VF_CAP_PropValueHead(entry, argv[i]);
 688          iter != NULL;  
 689          iter = VF_CAP_PropValueNext(iter)){
 690       val = VF_CAP_PropValueGet(iter);
 691       printf("    ");
 692       vf_sexp_pp(val);
 693     }
 694     vf_sexp_free(&entry);
 695   }
 696 
 697 #else
 698   int    i;
 699   SEXP   fontclass, fontdirs, extensions, pixel, point;
 700   struct s_capability_table  ct[] = {
 701     {"font-class",  CAPABILITY_STRING, CAPABILITY_ESSENTIAL, &fontclass}, 
 702     {"directories", CAPABILITY_LIST,   CAPABILITY_OPTIONAL,  &fontdirs}, 
 703     {"extensions",  CAPABILITY_LIST,   CAPABILITY_OPTIONAL,  &extensions}, 
 704     {"pixel-size",  CAPABILITY_STRING, CAPABILITY_OPTIONAL,  &pixel}, 
 705     {"point-size",  CAPABILITY_STRING, CAPABILITY_OPTIONAL,  &point}, 
 706     {NULL, 0, 0, NULL}
 707   };
 708 
 709   if (argc < 3){
 710     printf("Usage: ./a.out VFLIBCAP ENTRY\n");
 711     exit(1);
 712   }
 713   VF_CAP_Init(argv[1], NULL);
 714   if (VF_CAP_GetParsedFontEntry(argv[2], ct) < 0){
 715     printf("not found\n");
 716     exit(0);
 717   }
 718   for (i = 0; ct[i].cap != NULL; i++){
 719     if (*(ct[i].val) != NULL){
 720       printf("\"%s\": \n", ct[i].cap);
 721       printf("    ");
 722       vf_sexp_pp(*(ct[i].val));
 723     }
 724     vf_sexp_free(ct[i].val);
 725   }
 726 #endif
 727 
 728   return 0;
 729 }
 730 
 731 char*
 732 VF_CAP_GetEntry(char *entry)
     /* [<][>][^][v][top][bottom][index][help] */
 733 {
 734   return NULL;
 735 }
 736 char*
 737 VF_CAP_GetString(char *entry)
     /* [<][>][^][v][top][bottom][index][help] */
 738 {
 739   return NULL;
 740 }
 741 #endif
 742 
 743 /*EOF*/
 744 

/* [<][>][^][v][top][bottom][index][help] */