/*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * This file is distributed subject to a Software License Agreement found * in the file LICENSE that is included with this distribution. \*************************************************************************/ /* $Log: namelist_pp.c,v $ Revision 1.7 2010/02/08 16:43:05 soliday Added (char*) in front of quoted strings because c++ on solaris prints a bunch of warning messages if it has to convert literal strings into char* Revision 1.6 2007/08/07 16:15:29 ywang25 Replace strcpy with stcpy_ss to avoid potential memory problems. Revision 1.5 2003/07/22 23:25:30 soliday Added return statement. Revision 1.4 2002/08/14 16:23:49 soliday Added Open License Revision 1.3 1999/05/28 14:54:05 soliday Removed compiler warnings under Linux. Revision 1.2 1995/09/05 21:21:37 saunders First test release of the SDDS1.5 package. */ /* program: namelist_pp * purpose: namelist pre-processor for C programs * format of namelist input: * #namelist namelist_name[,options...] * definition_of_single_variable [={optional multiline initialization}]; * . * . * . * #endlist * Allowed types for variables are: int, short, float, double, STRING. * * Michael Borland, 1988 */ #include "mdb.h" #include "buffer.h" #define MAX_SUBSCRIPTS 100 #define SUBSCRIPT_LENGTH 20 #if defined(__TURBOC__) #define STRING_LENGTH 256 #else #define STRING_LENGTH 1024 #endif #define MAX_VARIABLES 100 #define MAX_NAMELISTS 100 long get_subscripts(char subs[MAX_SUBSCRIPTS][SUBSCRIPT_LENGTH], long max_subs, char *variable); char *efgets(char *s, long n, FILE *fp); int has_semicolon(char *s); #define USAGE "nlpp inputfile[.nl] [outputfile[.h]]" #define SET_STATIC 0 #define SET_EXTERN 1 #define SET_STRUCT 2 #define SET_AUTO 3 #define SET_NOINIT 4 #define N_OPTIONS 5 char *option[N_OPTIONS] = { "static", "extern", "struct", "auto", "noinit", } ; int main(argc, argv) int argc; char **argv; { char s[STRING_LENGTH], *ptr, *ptr1; char variable_name[MAX_VARIABLES][STRING_LENGTH]; char type_name[MAX_VARIABLES][STRING_LENGTH]; char namelist_name[MAX_NAMELISTS][STRING_LENGTH]; long n_subscripts[MAX_SUBSCRIPTS]; char subscript[MAX_SUBSCRIPTS][SUBSCRIPT_LENGTH]; char input[100], output[100], tmp_buf[100]; FILE *fpi, *fpo; long n_lines, n_variables, n_namelists; long i, j, use_struct, no_init; char definition_prefix[100], struct_name[100]; if (argc!=2 && argc!=3) bomb(NULL, USAGE); strcpy_ss(input, *++argv); if ((ptr=strchr(input, '.'))==NULL) { sprintf(output, "%s.h", input); strcat(input, ".nl"); } else { *ptr = 0; sprintf(output, "%s.h", input); *ptr = '.'; } if (argc==3) { strcpy_ss(output, *++argv); if ((ptr=strchr(output, '.'))==NULL) strcat(output, ".h"); } fpi = fopen_e(input , "r", 0); fpo = fopen_e(output, "w", 0); n_lines = n_namelists = 0; while (fgets(s, STRING_LENGTH, fpi)) { n_lines++; if (s[0]!='#' || strncmp(s+1, "namelist", 8)!=0) { fputs(s, fpo); continue; } strcpy_ss(s, s+9); if ((ptr=get_token_buf(s, namelist_name[n_namelists], STRING_LENGTH))==NULL) { printf("error on line %ld: no name for namelist\n", n_lines); exit(1); } use_struct = no_init = 0; strcpy_ss(definition_prefix, "static "); while ((ptr=get_token_buf(s, tmp_buf, 100))) { if ((ptr1=strchr(ptr, '/'))) *ptr1++ = 0; switch (match_string(ptr, option, N_OPTIONS, 0)) { case SET_STATIC: strcpy_ss(definition_prefix, "static "); break; case SET_EXTERN: strcpy_ss(definition_prefix, "extern "); break; case SET_STRUCT: use_struct = 1; if (ptr1) { strcpy_ss(struct_name, ptr1); if (strcmp(struct_name, namelist_name[n_namelists])==0) bomb("structure name can't be the same as the namelist name", NULL); } else sprintf(struct_name, "%s_struct", namelist_name[n_namelists]); break; case SET_AUTO: strcpy_ss(definition_prefix, "auto "); break; default: printf("error: unknown namelist option: %s\n", ptr); exit(1); break; } } n_variables = 0; if (use_struct) { fprintf(fpo, "typedef struct {\n"); if (!buffer_exists("dimensions")) create_buffer("dimensions", 10); else clear_buffer("dimensions"); if (!buffer_exists("initializations")) create_buffer("initializations", 10); else clear_buffer("initializations"); } while (efgets(s, STRING_LENGTH, fpi) && s[0]!='#') { n_lines++; if (get_token_buf(s, type_name[n_variables], STRING_LENGTH)==NULL) { printf("error on line %ld: no type name\n", n_lines); exit(1); } if (get_token_buf(s, variable_name[n_variables], STRING_LENGTH)==NULL) { printf("error on line %ld: no variable name\n", n_lines); exit(1); } if (!use_struct) { fprintf(fpo, "%s%s %s%s;\n", definition_prefix, type_name[n_variables], variable_name[n_variables], s); if ((ptr=strchr(variable_name[n_variables], '['))) { *ptr = 0; fprintf(fpo, "%s%s %s_default[%s%s;\n", definition_prefix, type_name[n_variables], variable_name[n_variables], ptr+1, s); *ptr = '['; } else { fprintf(fpo, "%s%s %s_default%s;\n", definition_prefix, type_name[n_variables], variable_name[n_variables], s); } n_subscripts[n_variables] = get_subscripts(subscript, MAX_SUBSCRIPTS, variable_name[n_variables]); if (n_subscripts[n_variables]!=0) { fprintf(fpo, "%s long %s_dimen[%ld] = { ", definition_prefix, variable_name[n_variables], n_subscripts[n_variables]); for (i=0; i=max_subs) { printf("error: variable %s uses too many subscripts\n", variable); exit(1); } } return(n_subs); } char *efgets(char *s, long n, FILE *fp) { register char *sr; sr = s; if (!fgets(sr, n, fp)) return(NULL); if (sr[0]=='#') return(s); while (!has_semicolon(sr)) { sr = s + strlen(s); fgets(sr, n, fp); } return(s); } int has_semicolon(char *s) { register char *ptr; ptr = s; while (*ptr && *ptr!=';') { if (*ptr=='"') { ptr++; while (*ptr!='"') ptr++; ptr++; } else if (*ptr=='\'') { ptr++; while (*ptr!='\'') ptr++; ptr++; } else ptr++; } if (*ptr==';') { *ptr = 0; return(1); } return(0); }