コード例 #1
0
int main(int argc, char *argv[])
{
	List list;
	List_node *abc;

	list_init(&list);

	check(list_size(&list) == 0);
	list_insert(&list, "abc");
	check(list_size(&list) == 1);
	abc = list_lookup_data(&list, "abc", cmp_string);
	check(abc != NULL);
	check(list_lookup(&list, abc) == abc);
	check(list_lookup_data(&list, "def", cmp_string) == NULL);
	check(cmp_string((char *) list_head(&list)->data, "abc") == 0);
	list_insert(&list, "def");
	check(list_size(&list) == 2);
	check(cmp_string((char *) list_head(&list)->data, "def") == 0);
	list_delete(&list, abc);
	check(list_lookup_data(&list, "abc", cmp_string) == NULL);
	list_delete_data(&list, "def", cmp_string);
	check(list_size(&list) == 0);

	list_free(&list, NULL);

	return 0;
}
コード例 #2
0
ファイル: res32.c プロジェクト: bilboed/wine
/* resources are stored first by type, then by name, then by language */
static int cmp_res( const void *ptr1, const void *ptr2 )
{
    const struct resource *res1 = ptr1;
    const struct resource *res2 = ptr2;
    int ret;

    if ((ret = cmp_string( &res1->type, &res2->type ))) return ret;
    if ((ret = cmp_string( &res1->name, &res2->name ))) return ret;
    return res1->lang - res2->lang;
}
コード例 #3
0
ファイル: new_parser.C プロジェクト: calebbuahin/SPRNT
/* return 1, 60, or 3600, -1 if error */
double convert_time_scale(char *t, Descriptor *des) {
  double rc = -1.0;

  if ( cmp_string(t, des[0]._key) ) {
    rc = 1.0;
  } else if ( cmp_string(t, des[1]._key) ) {
    rc = 60.0;
  } else if ( cmp_string(t, des[2]._key) ) {
    rc = 3600.0;
  } 
  return rc;
}
コード例 #4
0
ファイル: iniparsertest.c プロジェクト: bzero/POSApp
void validate_modelo(CuTest* tc, const char * modelo_name)
{
	struct keys {
		char* align;
		int fontsize;
		char* content;
		char* img;
		char* barcode_value;
		char* barcode_type;
		int barcode_height;
		int barcode_width;
	} keytab[] = {
		"center",1,"{Codigo} - {PedidoId}\\n",NULL,NULL,NULL,-1,-1,
		"center",-1,NULL,"l2ea",NULL,NULL,-1,-1,
		"center",-1,NULL,"l2eb",NULL,NULL,-1,-1,
		"center",2,"EVENTO DEMONSTRATIVO\\n\\nPISTA 5\\nUNISSEX -  {Tipo}\\nR$$ {Valor}\\n",NULL,NULL,NULL,-1,-1,
		"center",1,"1° EDIÇÃO - SERTANEJO NA VEIA\\n",NULL,NULL,NULL,-1,-1,
		"center",1,"\\n{Codigo}\\n",NULL,"{Codigo}","I2of5",96,2,
		"center",1,"Visite:\\nwww.<b>TICPLUS</b>.com",NULL,NULL,NULL,-1,-1,
	};
	int numkeys = sizeof(keytab)/sizeof(keytab[0]);
	dictionary* ini = iniparser_load(modelo_name);
	int i;
	CuAssertTrue(tc,NULL!=ini);	
	for (i=0;i<numkeys;i++) {
		char buf[128];
		sprintf(buf,"report_%d:align\0",i+1);
		CuAssertTrue(tc,0==cmp_string(keytab[i].align,iniparser_getstring(ini,buf,NULL)));
		sprintf(buf,"report_%d:fontsize\0",i+1);
		CuAssertTrue(tc,keytab[i].fontsize==iniparser_getint(ini,buf,-1));
		sprintf(buf,"report_%d:content\0",i+1);	
		CuAssertTrue(tc,0==cmp_string(keytab[i].content,iniparser_getstring(ini,buf,NULL)));
		sprintf(buf,"report_%d:img\0",i+1);
		CuAssertTrue(tc,0==cmp_string(keytab[i].img,iniparser_getstring(ini,buf,NULL)));
		sprintf(buf,"report_%d:barcode_value\0",i+1);	
		CuAssertTrue(tc,0==cmp_string(keytab[i].barcode_value,iniparser_getstring(ini,buf,NULL)));
		sprintf(buf,"report_%d:barcode_type\0",i+1);	
		CuAssertTrue(tc,0==cmp_string(keytab[i].barcode_type,iniparser_getstring(ini,buf,NULL)));
		sprintf(buf,"report_%d:barcode_height\0",i+1);
		CuAssertTrue(tc,keytab[i].barcode_height==iniparser_getint(ini,buf,-1));
		sprintf(buf,"report_%d:barcode_width\0",i+1);
		CuAssertTrue(tc,keytab[i].barcode_width==iniparser_getint(ini,buf,-1));
	}
}		
コード例 #5
0
ファイル: new_parser.C プロジェクト: calebbuahin/SPRNT
FirstDef decipher_keyword(char *pt, Descriptor *des, int sz) {
  FirstDef rc = def_not_found;

  for (int jj=0; jj<sz; jj++) {
    if ( cmp_string(pt, des[jj]._key)) {
      rc = (FirstDef)jj;
      break;
    }
  }
  return rc;
}
コード例 #6
0
ファイル: res32.c プロジェクト: AlexSteel/wine
/* get rid of duplicate resources with different versions */
static void remove_duplicate_resources( DLLSPEC *spec )
{
    unsigned int i, n;

    for (i = n = 0; i < spec->nb_resources; i++, n++)
    {
        if (i && !cmp_string( &spec->resources[i].type, &spec->resources[i-1].type ) &&
            !cmp_string( &spec->resources[i].name, &spec->resources[i-1].name ) &&
            spec->resources[i].lang == spec->resources[i-1].lang)
        {
            if (spec->resources[i].version == spec->resources[i-1].version)
            {
                char *type_str = format_res_string( &spec->resources[i].type );
                char *name_str = format_res_string( &spec->resources[i].name );
                error( "winebuild: duplicate resource type %s name %s language %04x version %08x\n",
                       type_str, name_str, spec->resources[i].lang, spec->resources[i].version );
            }
            else n--;  /* replace the previous one */
        }
        if (n < i) spec->resources[n] = spec->resources[i];
    }
    spec->nb_resources = n;
}
コード例 #7
0
ファイル: JSON.cpp プロジェクト: tomazos/Folderscope
SInt64 JSON::comparef(const JSON& a, const JSON& b)
{
	switch (a.m_type)
	{
	case e_null: 
		switch (b.m_type)
		{
			case e_null: return cmp_null(a,b);
			case e_bool: return cmp_bool(a,b);
			case e_integer: return cmp_integer(a,b);
			case e_real: return cmp_real(a,b);
			case e_string: return cmp_string(a,b);
			case e_array: return cmp_array(a,b);
			case e_object: return cmp_object(a,b);
		}

	case e_bool:
		switch (b.m_type)
		{
			case e_null: return cmp_bool(a,b);
			case e_bool: return cmp_bool(a,b);
			case e_integer: return cmp_integer(a,b);
			case e_real: return cmp_real(a,b);
			case e_string: return cmp_string(a,b);
			case e_array: return cmp_array(a,b);
			case e_object: return cmp_object(a,b);
		}

	case e_integer:
		switch (b.m_type)
		{
			case e_null: return cmp_integer(a,b);
			case e_bool: return cmp_integer(a,b);
			case e_integer: return cmp_integer(a,b);
			case e_real: return cmp_real(a,b);
			case e_string: return cmp_string(a,b);
			case e_array: return cmp_array(a,b);
			case e_object: return cmp_object(a,b);
		}

	case e_real:
		switch (b.m_type)
		{
			case e_null: return cmp_real(a,b);
			case e_bool: return cmp_real(a,b);
			case e_integer: return cmp_real(a,b);
			case e_real: return cmp_real(a,b);
			case e_string: return cmp_string(a,b);
			case e_array: return cmp_array(a,b);
			case e_object: return cmp_object(a,b);
		}

	case e_string:
		switch (b.m_type)
		{
			case e_null: return cmp_string(a,b);
			case e_bool: return cmp_string(a,b);
			case e_integer: return cmp_string(a,b);
			case e_real: return cmp_string(a,b);
			case e_string: return cmp_string(a,b);
			case e_array: return cmp_array(a,b);
			case e_object: return cmp_object(a,b);
		}

	case e_array:
		switch (b.m_type)
		{
			case e_null: return cmp_array(a,b);
			case e_bool: return cmp_array(a,b);
			case e_integer: return cmp_array(a,b);
			case e_real: return cmp_array(a,b);
			case e_string: return cmp_array(a,b);
			case e_array: return cmp_array(a,b);
			case e_object: return cmp_object(a,b);
		}

	case e_object:
		switch (b.m_type)
		{
			case e_null: return cmp_object(a,b);
			case e_bool: return cmp_object(a,b);
			case e_integer: return cmp_object(a,b);
			case e_real: return cmp_object(a,b);
			case e_string: return cmp_object(a,b);
			case e_array: return cmp_object(a,b);
			case e_object: return cmp_object(a,b);
		}
	}

	Check();
	return -1;
}
コード例 #8
0
ファイル: res32.c プロジェクト: bilboed/wine
/* build the 3-level (type,name,language) resource tree */
static struct res_tree *build_resource_tree( DLLSPEC *spec, unsigned int *dir_size )
{
    unsigned int i, k, n, offset, data_offset;
    struct res_tree *tree;
    struct res_type *type = NULL;
    struct res_name *name = NULL;
    struct resource *res;

    qsort( spec->resources, spec->nb_resources, sizeof(*spec->resources), cmp_res );

    tree = xmalloc( sizeof(*tree) );
    tree->types = NULL;
    tree->nb_types = 0;

    for (i = 0; i < spec->nb_resources; i++)
    {
        if (!i || cmp_string( &spec->resources[i].type, &spec->resources[i-1].type ))  /* new type */
        {
            type = add_type( tree, &spec->resources[i] );
            name = add_name( type, &spec->resources[i] );
        }
        else if (cmp_string( &spec->resources[i].name, &spec->resources[i-1].name )) /* new name */
        {
            name = add_name( type, &spec->resources[i] );
        }
        else if (spec->resources[i].lang == spec->resources[i-1].lang)
        {
            char *type_str = format_res_string( &spec->resources[i].type );
            char *name_str = format_res_string( &spec->resources[i].name );
            error( "winebuild: duplicate resource type %s name %s language %04x\n",
                   type_str, name_str, spec->resources[i].lang );
        }
        else name->nb_languages++;
    }

    /* compute the offsets */

    offset = RESDIR_SIZE( tree->nb_types );
    for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
    {
        type->dir_offset = offset;
        offset += RESDIR_SIZE( type->nb_names );
        for (n = 0, name = type->names; n < type->nb_names; n++, name++)
        {
            name->dir_offset = offset;
            offset += RESDIR_SIZE( name->nb_languages );
        }
    }
    data_offset = offset;
    offset += spec->nb_resources * RESOURCE_DATA_ENTRY_SIZE;

    for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
    {
        if (type->type->str)
        {
            type->name_offset = offset | 0x80000000;
            offset += (strlenW(type->type->str)+1) * sizeof(WCHAR);
        }
        else type->name_offset = type->type->id;

        for (n = 0, name = type->names; n < type->nb_names; n++, name++)
        {
            if (name->name->str)
            {
                name->name_offset = offset | 0x80000000;
                offset += (strlenW(name->name->str)+1) * sizeof(WCHAR);
            }
            else name->name_offset = name->name->id;
            for (k = 0, res = name->res; k < name->nb_languages; k++, res++)
            {
                unsigned int entry_offset = (res - spec->resources) * RESOURCE_DATA_ENTRY_SIZE;
                res->data_offset = data_offset + entry_offset;
            }
        }
    }
    if (dir_size) *dir_size = (offset + 3) & ~3;
    return tree;
}
コード例 #9
0
ファイル: main.c プロジェクト: granberro/uLoader
char * syscall_open_func( char *name, int mode)
{
    int n;

    syscall_open_mode=mode;


    if(!cmp_string(name,"no_mload")) {
        flag_no_mload=1;
        return name;
    }

    if(flag_no_mload && !cmp_string(name,"/dev/mload"))
    {
        return dev_kk;
    }

    if(disable_ffs)
    {
        if(flag_no_mload && !cmp_string(name,"fat"))
        {
            return dev_kk;
        }
    }

    if(!flag_emu || disable_ffs)
        return name;

    // RB game identification
    if (game == 0) {
        if (!cmp_string(name, "/title/00010000/535a4145"))
            game = 2; // RB2
        if (!cmp_string(name, "/title/00010000/535a4245"))
            game = 3; // RB3
    }

    // It's time to use emulated files for RB2
    if (game_loading && !cmp_string(name, "/title/00010000/535a4145/data/rockbnd2.dat")) {
        game_loading=0;
    }

    // Avoid nand emulation during game loading (RB2)
    if (game_loading && game == 2 &&
            (!cmp_string(name, "/title/00010005") || !cmp_string(name, "/ticket/00010005"))) {
        return "/ticket/00010005/00000000.tik";
    }

    // Avoid looking for non existant files
    if (game == 2) {
        if (!cmp_string(name, "/ticket/00010005")) {
            if (!cmp_string(name, "/ticket/00010005/735a4145.tik") ||
                    !cmp_string(name, "/ticket/00010005/735a4245.tik") ||
                    !cmp_string(name, "/ticket/00010005/735a4345.tik") ||
                    !cmp_string(name, "/ticket/00010005/735a4445.tik") ||
                    !cmp_string(name, "/ticket/00010005/735a4545.tik")) {
            }
            else
                return "/ticket/00010005/00000000.tik";
        }
    }

    // Avoid looking for non existant files
    if (game == 3) {
        if (!cmp_string(name, "/ticket/00010005")) {
            if (!cmp_string(name, "/ticket/00010005/735a4145.tik") ||
                    !cmp_string(name, "/ticket/00010005/735a4245.tik") ||
                    !cmp_string(name, "/ticket/00010005/735a4345.tik") ||
                    !cmp_string(name, "/ticket/00010005/735a4445.tik") ||
                    !cmp_string(name, "/ticket/00010005/735a4545.tik") ||
                    !cmp_string(name, "/ticket/00010005/735a4a45.tik") ||
                    !cmp_string(name, "/ticket/00010005/735a4b45.tik") ||
                    !cmp_string(name, "/ticket/00010005/735a4c45.tik") ||
                    !cmp_string(name, "/ticket/00010005/735a4d45.tik")) {
            }
            else
                return "/ticket/00010005/00000000.tik";
        }
    }


    if(name[0]=='#') // for example #/title/xxxx : can be used to skip this function to open files
    {
        name++;
        for(n=0; name[n]; n++) sys_name[n+32]=name[n];
        sys_name[n+32]=0;
        name=(char *) sys_name+32;

    }
    else if(!cmp_string(name,"/dev/stm/immediate"))
    {
        static char stm[] ATTRIBUTE_ALIGN(32)=DEVICE_FAT"/dev/immediate";
        name++;

        for(n=0; stm[n]; n++) sys_name[n+32]=stm[n];
        sys_name[n+32]=0;

        name=(char *) sys_name+32;
    }
    else if(sd_mounted>0 && !cmp_string(name,"/dev/sdio"))
コード例 #10
0
ファイル: new_parser.C プロジェクト: calebbuahin/SPRNT
// top level function to parse the spt netlist and construct the SUBCATCHMENT object
// as well as modifying the Options and Sgraph objects
int read_spt_from_file(FILE* F, Subcatchment *SUB, NameStore *NODE_NAMES, SMap *HASH, FILE* out) {

  FirstDef rc;
  int r_code;
  int line_num, good, node_index;
  source_id src_id;
  unsigned int n_op,n_node, n_seg, n_junc, n_qs, n_ls, n_bdn;
  StrBuffer *Prime, *Second;
  SimpleDblArray dba;
  double *XX=NULL, *YY=NULL;

  FlexVec<int, SHORT_ARRY_LENGTH>  qsources; // we store index only
  FlexVec<int, SHORT_ARRY_LENGTH>  lsources;
  FlexVec<int, SHORT_ARRY_LENGTH>  asources;
  
  ChkSum   mychk;
  char     chktmp[10];

  Prime = new StrBuffer(1023);  // both arrayes can automatically grow if needed
  Second = new StrBuffer(4095);
  r_code = -1;      // by default, the return code indicates failure
  
  /* we first read the option blocks */
  rc = def_not_found;
  line_num = 0;
  
  n_op = n_node = n_seg = n_junc = n_qs = n_ls = n_bdn = 0;
  while (1) { // first do the tally, and a rough check
    rc = search_block(F, &line_num, Spt_Descriptor, DES_SIZE(Spt_Descriptor), Prime, Second, out); 
    switch (rc) {
    case p_options: n_op++; break;
    case p_node:  n_node++; break;
    case p_segment: n_seg++; break;
    case p_junction: n_junc++; break;
    case p_qsource: n_qs++; break;
    case p_lateralsource: n_ls++; break;
    case p_boundarycondition: n_bdn++; break;
    case def_not_found: break;
    case def_error: 
      goto back;
      break;
    default: break;
    }
    if ( rc == def_not_found ) break;
  }
  rewind(F);
  
  if (out) {
    fprintf(out,"[II]: Found %d nodes, %d segmetns, %d junctions, %d q_sources, %d lateral sources, %d bdn condtions, %d options in the netlist\n", 
	    n_node, n_seg, n_junc, n_qs, n_ls, n_bdn, n_op);
  }
  if ( n_node < 2 ) {
    if (out) fprintf(out, "Bummer: not enough node statements, unable to procced\n");
    goto back;
  } else if ( n_seg < 1 ) {
    if (out) fprintf(out, "Bummer: not enough segment statements, unable to procced\n");
    goto back;
  } else if ( n_qs < 1 ) {
    if (out) fprintf(out, "Bummer: not enough Q source statements, unable to procced\n");
    goto back;
  } else if ( n_bdn < 1 ) {
    if (out) fprintf(out, "Bummer: not enough boundary condition statements, unable to procced\n");
    goto back;
  }
  
  // Copy the stat into the STAT object
  STAT.N_Nodes() = n_node;
  STAT.N_Segs() = n_seg;
  STAT.N_Juncs() = n_junc;
  STAT.N_Qsrcs() = n_qs;
  STAT.N_Lsrcs() = n_ls;
  STAT.N_Bnds() = n_bdn;

  // do the memory allocation stuff here
  NODE_NAMES->Init(n_node);
  SUB->InitGraph(n_node, n_seg, n_junc); //Testing

  // allocate memory to store the boundary conditions
  qsources.size(n_node+10);
  lsources.size(n_node+10);
  asources.size(n_node+10);

  for (unsigned int jj=0; jj<n_node+10; jj++) qsources[jj]=-1;
  for (unsigned int jj=0; jj<n_node+10; jj++) lsources[jj]=-1;
  for (unsigned int jj=0; jj<n_node+10; jj++) asources[jj]=-1;

  // we now proess options, otherwise we use default values
  if ( n_op > 0 ) {
    char *tmp;
    double stoptimeunit=1.0, timestepunit=1.0, prtintervalunit=1.0;
    double stoptime=-1.0, timestep=0.0, prtinterval=0.0;
    double prtstartunit = 1.0, prtstart = 0.0;
    double spinuptime = 0.0;

    rewind(F);
    rc = def_not_found;
    line_num = 0;
    while (1) {  
      rc = search_block(F, &line_num, Spt_Descriptor, DES_SIZE(Spt_Descriptor), Prime, Second, NULL); 
      
      if (rc == def_not_found ) break;
      if (rc != p_options ) continue;
      
      // read the options, in particular UseMetric!     
      good = Prime->Separate(out);
      if (good<0) {
	if (out) fprintf(out,"Bummer: Syntax error in netlist specification at line %d\n", line_num);
	goto back;
      }
      tmp = Prime->Find_Value( Op_Descriptor[0]._key); // USEMETRIC
      if (tmp) {
	OPT.UseMetric() = atoi(tmp)>0 ? 1 : 0;
	if (out) fprintf(out,"[II]: Metric set to %d\n", OPT.UseMetric());
      }

      // we process unit first so that we don't have to worry later
      tmp = Prime->Find_Value( Op_Descriptor[2]._key); // TIMESTEPUNIT
      if (tmp) {
	timestepunit = convert_time_scale(tmp, Time_Descriptor);
      }
      if ( timestepunit < 0 ) {
	if (out) fprintf(out,"[WW]: only accept time unit of SECOND, MINUTE, HOUR for statement on line %d. Use default=SECOND. \n", 
			 Prime->LineNumber());
	timestepunit = 1.0;
      }
      
      tmp = Prime->Find_Value( Op_Descriptor[1]._key); // TIMESTEP
      if (tmp) timestep = atof(tmp);

      tmp = Prime->Find_Value( Op_Descriptor[4]._key); // STOPTIMEUNIT
      if (tmp) {
	stoptimeunit = convert_time_scale(tmp, Time_Descriptor);
      }
      if ( stoptimeunit < 0 ) {
	if (out) fprintf(out,"Bummer:only accept time unit of SECOND, MINUTE, HOUR for statement on line %d. Use default=SECOND. \n", 
			 Prime->LineNumber());
	stoptimeunit = 1.0;
      }

      tmp = Prime->Find_Value( Op_Descriptor[3]._key); // STOPTIME
      if (tmp) stoptime = atof(tmp);

      // also deal with print interval first
      tmp = Prime->Find_Value( Op_Descriptor[6]._key); // PRTINTERVALUNIT
      if (tmp) {
	prtintervalunit = convert_time_scale(tmp, Time_Descriptor);
      }
      if ( prtintervalunit < 0 ) {
	if (out) fprintf(out,"[WW]: only accept time unit of SECOND, MINUTE, HOUR for statement on line %d. Use default=SECOND. \n", 
			 Prime->LineNumber());
	prtintervalunit = 1.0;
      }

      
      tmp = Prime->Find_Value( Op_Descriptor[8]._key); // PRTSTARTUNIT
      if (tmp) {
	prtstartunit = convert_time_scale(tmp, Time_Descriptor);
      }
      if ( prtstartunit < 0 ) {
	if (out) fprintf(out,"[WW]: only accept time unit of SECOND, MINUTE, HOUR for statement on line %d. Use default=SECOND. \n", 
			 Prime->LineNumber());
	prtstartunit = 1.0;

      }

      tmp = Prime->Find_Value( Op_Descriptor[7]._key); // PRTSTART
      if (tmp) prtstart = atof(tmp);

      tmp = Prime->Find_Value( Op_Descriptor[5]._key); // PRTINTERVAL
      if (tmp) prtinterval = atof(tmp);
      if ( prtinterval < 0 ) {
	if (out) fprintf(out,"[WW]: negative print interval specified on line %d. Overwritten with zero!\n",
			 Prime->LineNumber());
	prtinterval = 0.0;
      }
      
      tmp = Prime->Find_Value( Op_Descriptor[9]._key); // CHECKONLY
      if (tmp) {
	OPT.CheckOnly() = atoi(tmp) > 0 ? 1 : 0;
	if (out) fprintf(out,"[II]: CheckOnly set to %d\n", OPT.CheckOnly());
      }
      
      tmp = Prime->Find_Value( Op_Descriptor[10]._key); // SSFILE
      if (tmp) {
	STAT.SetSSFile(tmp);
	if (out) fprintf(out, "[II]: SSFile (SteadyState file) set to \"%s\"\n", tmp);
      }

      tmp = Prime->Find_Value( Op_Descriptor[11]._key); // Lmax
      if (tmp) {
	OPT.LMax() = atof(tmp);
	if (out) fprintf(out,"[II]: LMax set to %.4e\n", OPT.LMax() );
      }

      tmp = Prime->Find_Value( Op_Descriptor[12]._key); // Lmin
      if (tmp) {
	OPT.LMin() = atof(tmp);
	if (out) fprintf(out,"[II]: LMin set to %.4e\n", OPT.LMin() );
      }

      tmp = Prime->Find_Value( Op_Descriptor[13]._key); // PrintDepth
      if (tmp) {
	OPT.PrintD() = atoi(tmp) > 0 ? 1 : 0;
	if (out) fprintf(out,"[II]: PrtDepth set to %1d\n", OPT.PrintD() );
      }

      tmp = Prime->Find_Value( Op_Descriptor[14]._key); // PrintSurfElev
      if (tmp) {
	OPT.PrintZ() = atoi(tmp) > 0 ? 1 : 0;
	if (out) fprintf(out,"[II]: PrtSurfElev set to %1d\n", OPT.PrintZ() );
      }

      tmp = Prime->Find_Value( Op_Descriptor[15]._key); // PrintQ
      if (tmp) {
	OPT.PrintQ() = atoi(tmp) > 0 ? 1 : 0;
	if (out) fprintf(out,"[II]: PrtQ set to %1d\n", OPT.PrintQ() );
      }

      tmp = Prime->Find_Value( Op_Descriptor[16]._key); // PrintA
      if (tmp) {
	OPT.PrintA() = atoi(tmp) > 0 ? 1 : 0;
	if (out) fprintf(out,"[II]: PrtA set to %1d\n", OPT.PrintA() );
      }

      tmp = Prime->Find_Value( Op_Descriptor[17]._key); // PrintCoord
      if (tmp) {
	OPT.PrintXY() = atoi(tmp) > 0 ? 1 : 0;
	if (out) fprintf(out,"[II]: PrtCoord set to %1d\n", OPT.PrintXY() );
      }

      tmp = Prime->Find_Value( Op_Descriptor[18]._key); // verbose
      if (tmp) {
	OPT.DebugLevel() = atoi(tmp) > 0 ? atoi(tmp) : 0;
	if (out) fprintf(out,"[II]: Verbose set to %1d\n", OPT.DebugLevel() );
      }

      tmp = Prime->Find_Value( Op_Descriptor[19]._key); // epoch
      if (tmp) {
	STAT.SetEpoch(tmp);
	if (out) fprintf(out, "[II]: Epoch is set to %s\n", STAT.Epoch() );
      }

      tmp = Prime->Find_Value( Op_Descriptor[20]._key); // spinup_time
      if (tmp) spinuptime = atof(tmp);
      if ( spinuptime < 0 ) {
	if (out) fprintf(out,"[WW]: negative spin-up time specified on line %d. Use zero instead (disabled)\n",
			 Prime->LineNumber());
	spinuptime = 0.0;
      }
      
    }

    // check if stoptime is specified (by setting default to 0), 
    // do the scaling,
    // reason: we might have multiple option blocks

    if ( timestep < 0 ) {
      if (out) fprintf(out,"[WW]: negative TimeStep specified. Overwritten with zeor!\n");
    } else if (timestep > 0) {
      timestep *= timestepunit;
      OPT.FixedStep() = timestep;
      if (out) fprintf(out,"[II]: TimeStep set to %.3e second.\n", timestep);
    }
    
    if ( prtinterval < 0 ) {
      if (out) fprintf(out,"[WW]: negative PrInterval specified. Overwritten with zero!\n");
    } else if (prtinterval>0) {
      int tt;
      prtinterval *= prtintervalunit;
      tt = (int) round(prtinterval/60.0);
      tt = tt >=0 ? tt : 0;
      OPT.PrintInterval() = tt;
      if (out) fprintf(out,"[II]: PrtInterval set to %d min\n", tt);
    }

    if (prtstart < 0) {
      if (out) fprintf(out,"[WW]: negative PrtStart specified. Overwritten with zero!\n");
    } else if ( prtstart > 0) {
      int tt;
      prtstart *= prtstartunit;
      tt = (int)round(prtstart/60.0);
      tt = tt>=0 ? tt : 0;
      OPT.PrintStart() = tt;
      if (out) fprintf(out, "[II]: PrtStart set to %d min\n", tt);
    }

    if (stoptime > 0 ) {
      stoptime *= stoptimeunit;
      OPT.StopTime() = stoptime;
      if (out) fprintf(out,"[II]: StopTime set to %.3e second\n", stoptime);
    } else {
      if (out) fprintf(out,"Bummer: a positive StopTime is required in order to run the simulation!\n");
      goto back;
    }

    if ( spinuptime > 0 ) {
      int tt = (int)spinuptime;
      const int min_spin = 300;
      if ( tt > min_spin ) {
	OPT.SpinUpTime() = tt;
	if (out) fprintf(out,"[II]: SpinUpTime set to %d second\n", tt);
      } else {
	OPT.SpinUpTime() = 0;
	if (out) fprintf(out,"[WW]: minimal spinup time is %d seconds. Revert back to zero (spinup disabled)\n", min_spin);
      }
    }
  }
  
  
  // add nodes,  check duplicate
  rewind(F);
  rc = def_not_found;
  line_num = 0;
  while (1) {  
    char node_id[MAX_LINE_LENGTH];
    char *tmp;
    double s0, n, h0, z0, width, slope;
    XsecType xtp;
    int   num_pairs;
    double q0=0, a0=0;  // we will deal with them later
    double x=-1.0, y=-1.0;  // not used 

    rc = search_block(F, &line_num, Spt_Descriptor, DES_SIZE(Spt_Descriptor), Prime, Second, NULL); 
    
    // we don't check on the error flags since we have done it before
    if (rc == def_not_found ) break;   // we added all nodes
    if (rc == def_error ) goto back;  

    width = 0.0;
    slope = 0.0;
    num_pairs = 0;
    switch (rc) {
    case p_node:
      /* intercept and understand node */
      if ( !Second->HasContent()) {
	if (out) fprintf(out,"Bummer: NODE statement on line %d requires a x-section specification\n", Prime->LineNumber() );
	goto back;
      }
      good = Prime->Separate(out);
      good = Second->Separate(out);
      
      if (good <0) {
	if (out) fprintf(out,"Bummer: syntax error in netlist specification in line %d\n", Prime->LineNumber());
	goto back;
      }

      // parse each field one by one
      tmp = Prime->Find_Value( Node_Descriptor[0]._key); // "id"
      if (!tmp) {
	if (out) fprintf(out, "Bummer: unable to locate field %s for the NODE statement on line %d\n", Node_Descriptor[0]._key, 
			 Prime->LineNumber());
	goto back;
      }
      // the clean node id is now in node_id;
      strncpy(node_id, tmp, MAX_WORD_LENGTH);
      node_index = HASH->Check(node_id);
      if ( node_index != -1 ) {
	if (out) fprintf(out,"Bummer: duplicated NODE definition of node \"%s\" on line %d\n", node_id, Prime->LineNumber() );
	goto back;
      }
      node_index = HASH->Create(node_id);
      NODE_NAMES->Insert(node_id, node_index);
      
      tmp = Prime->Find_Value( Node_Descriptor[1]._key);  // "sR"
      if (!tmp) {
	if (out) fprintf(out, "Bummer: unable to locate field %s for the NODE statement on line %d\n", Node_Descriptor[1]._key, 
			 Prime->LineNumber());
	goto back;
      }
      s0 = atof(tmp);
      if ( s0 < 1e-6 ) {
	if (out) fprintf(out, "[WW]: reference slope sR at location %s is nonpositive with value of %.4e. \n", node_id, s0);
#if 0
	goto back;
#endif
      }

      tmp = Prime->Find_Value( Node_Descriptor[2]._key);  // "n"
      if (!tmp) {
	if (out) fprintf(out, "Bummer: unable to locate field %s for the NODE statement on line %d\n", Node_Descriptor[2]._key, 
			 Prime->LineNumber());
	goto back;
      }
      n = atof(tmp);
      if ( n < OPT.MinN() ) {
	if (out) fprintf(out,"[WW]: Manning's N at location %s is %.4e, less than threshold value %.4e. Supercritical flow might occur\n",
			 node_id, n, OPT.MinN());
      }
      
      tmp = Prime->Find_Value( Node_Descriptor[3]._key);  // "zR"
      if (!tmp) {
	if (out) fprintf(out, "Bummer: unable to locate field %s for the NODE statement on line %d\n", Node_Descriptor[3]._key, 
			 Prime->LineNumber());
	goto back;
      }
      z0 = atof(tmp);
      
      
      tmp = Prime->Find_Value( Node_Descriptor[4]._key);  // "hR"
      if (!tmp) {
	if (out) fprintf(out, "Bummer: unable to locate field %s for the NODE statement on line %d\n", Node_Descriptor[4]._key, 
			 Prime->LineNumber());
	goto back;
      }
      h0 = atof(tmp);
      
      tmp = Prime->Find_Value( Node_Descriptor[5]._key); // "xcoord"
      if (tmp) {
	x = atof(tmp);    // this is optional
      }

      tmp = Prime->Find_Value( Node_Descriptor[6]._key); // "ycoord"
      if (tmp) {
	y = atof(tmp);
      }

      if ( Second->Cmp_Head(Node_Descriptor[7]._key)) {   // "Trapezoidal
	tmp = Second->Find_Value(Trap_Descriptor[0]._key);  // "bottomwidth"
	if (!tmp) {
	  if (out) fprintf(out, "Bummer: %s x-section on line %d requires field %s\n", Node_Descriptor[5]._key, 
			   Second->LineNumber(), Trap_Descriptor[0]._key);
	  goto back;
	}
	width = atof(tmp);
	
	tmp = Second->Find_Value(Trap_Descriptor[1]._key);  // "slope"
	if (!tmp) {
	  if (out) fprintf(out, "Bummer: %s x-section on line %d requires field %s\n", Node_Descriptor[5]._key, 
			   Second->LineNumber(), Trap_Descriptor[1]._key);
	  goto back;
	} else {
	  slope = atof(tmp);
	}
	xtp = TRAP;
	
      } else if ( Second->Cmp_Head(Node_Descriptor[8]._key)) {  // "Rectangular"
	tmp = Second->Find_Value(Rect_Descriptor[0]._key);  // "bottomwidth"
	if (!tmp) {
	  if (out) fprintf(out, "Bummer: %s x-section on line %d requires field %s\n", Node_Descriptor[6]._key, 
			   Second->LineNumber(), Rect_Descriptor[0]._key);
	  goto back;
	} else {
	  width = atof(tmp);
	}
	xtp = RECT;
	
      } else if ( Second->Cmp_Head(Node_Descriptor[9]._key)) { // "XY"
	if ( Second->NumPairs() % 2 != 0 ) {
	  if (out) fprintf(out,"Bummer: unbalanced XY pairs for %s statement on line %d\n", 
			   Node_Descriptor[7]._key,Second->LineNumber());
	  goto back;
	  
	} else {  // all good, copy the values
	  dba.Reset();
	  num_pairs = read_2d_arrays(Second, XY_Descriptor, &dba, 0, out);
	  
	  if ( num_pairs <= 0 ) {
	    if (out) fprintf(out,"Bummer: error reading 2D data specified on line %d\n", Second->LineNumber() );
	    goto back;
	  }
	}
	xtp = SPLINE;
	
      } else {
	if (out) fprintf(out,"Bummer: NODE statement on line %d requires at least one of the x-section specification: %s, %s or %s\n",
			 Prime->LineNumber(), Node_Descriptor[5]._key, Node_Descriptor[6]._key, Node_Descriptor[7]._key);
	goto back;
      }
      
      // at this point, all variables are ready, create the node
      // use node_idx, s0, n, h0, z0, dba (good)
      // first do scaling based UseMetric()
      XX = dba.X();
      YY = dba.Y();
      if (OPT.UseMetric() == 0 ) {
	if (xtp == SPLINE) {
	  for (int jj=0; jj<num_pairs; jj++) {
	    XX[jj] *= OPT.FtoM();
	    YY[jj] *= OPT.FtoM();
	  }
	} else {  // RECT or TRAP, only change the bottom width, slope is dimensionless
	  width *= OPT.FtoM();
	}
	z0 *= OPT.FtoM();
	h0 *= OPT.FtoM();
      }
      
      if ( xtp == SPLINE ) {
#ifdef DBGSPLINE
	printf("node name %s, id %d\n", node_id, (unsigned int)node_index); 
#endif
	SUB->MakeNode((unsigned int)node_index, s0, n, x, y, q0, a0, z0, h0, SPLINE, num_pairs, XX, YY);
      } else if (xtp == TRAP) {
	SUB->MakeNode((unsigned int)node_index, s0, n, x, y, q0, a0, z0, h0, TRAP, width, slope);
      } else if (xtp == RECT) {
	SUB->MakeNode((unsigned int)node_index, s0, n, x, y, q0, a0, z0, h0, RECT, width);
      }
      
      break;

    default: break;

    } // end switch
  }   // while loop, find all nodes


  // make SUB happy
  SUB->AssignNodes();


  // records Qsrc, Lsrc and Bdn's
  rewind(F);
  rc = def_not_found;
  line_num = 0;
  while (1) {  
    char node_id[MAX_LINE_LENGTH];
    char *tmp;
    int   num_pairs;
    int loc_index, bnd_is_area;
    Node *node=NULL;
    //    double geo_scale=1.0;

    rc = search_block(F, &line_num, Spt_Descriptor, DES_SIZE(Spt_Descriptor), Prime, Second, NULL); 
    
    // we don't check on the error flags since we have done it before
    if (rc == def_not_found ) break;   // we added all nodes
    if (rc == def_error ) goto back;  

    num_pairs = 0;
    switch (rc) {
    case p_qsource:
      if (!Second->HasContent()) {
	if (out) fprintf(out,"Bummer: QSOURCE statement on line %d requires a time series specification\n", Prime->LineNumber() );
	goto back;
      }
      good = Prime->Separate(out);
      good = Second->Separate(out);
      
      if (good<0) {
	if (out) fprintf(out,"Bummer: syntax error in netlist specification in line %d\n", line_num);
	goto back;
      }

      tmp = Prime->Find_Value( Qsource_Descriptor[0]._key); // "location"
      if (!tmp) {
	if (out) fprintf(out, "Bummer: unable to locate field %s for the QSOURCE statement on line %d\n", Qsource_Descriptor[0]._key, 
			 Prime->LineNumber());
	goto back;
      }
      if ( !Second->Cmp_Head( Qsource_Descriptor[1]._key) ) { // "timeseries"
	if (out) fprintf(out,"Bummer: QSOURCE statement on line %d requires time series specification: %s\n",
			 Prime->LineNumber(), Qsource_Descriptor[1]._key);
	goto back;
      }

      strncpy(node_id, tmp, MAX_WORD_LENGTH);
      loc_index = HASH->Check(node_id);
      if ( loc_index == -1 ) {
	if (out) fprintf(out, "Bummer: cannot find node \"%s\" specified on line %d\n",
			 node_id, Prime->LineNumber());
	goto back;
      }
      
      dba.Reset();
      num_pairs = read_2d_arrays(Second, TS_Descriptor, &dba, 1, out);
      if ( num_pairs <= 0 ) {
	if (out) fprintf(out,"Bummer: error reading 2D data specified on line %d\n", Second->LineNumber() );
	goto back;
      }

      // ready to insert Q source, with node and time series in dba (good), remember the
      // dba.Scale() field, which is the time scale
      XX = dba.X();
      YY = dba.Y();
      src_id = SUB->MakeSource(num_pairs, &XX[0], &YY[0], dba.Scale(), (OPT.UseMetric()==0?OPT.F3toM3():1.0) );
      if (src_id<0) {
	if (out) fprintf(out,"Bummer: problem with QSource at node \"%s\" on line %d\n",
			 node_id, Prime->LineNumber());
	goto back;
      }
      
      if ( qsources[ loc_index] > -1 ) {
	if (out) fprintf(out, "Bummer: duplicated definitino of Qsource at node \"%s\"\n",
			 node_id);
	goto back;
      }

      qsources[ loc_index ] = src_id; // store the index
      break;

    case p_lateralsource:
      if (!Second->HasContent()) {
	if (out) fprintf(out,"Bummer: LATERALSOURCE statement on line %d requires a time series specification\n", Prime->LineNumber() );
	goto back;
      }
      good = Prime->Separate(out);
      good = Second->Separate(out);
      
      if (good<0) {
	if (out) fprintf(out,"Bummer: problem with LateralSource on line %d\n",
			 Prime->LineNumber());
	goto back;
      }

      tmp = Prime->Find_Value( Latsource_Descriptor[0]._key); // "location"
      if (!tmp) {
	if (out) fprintf(out, "Bummer: unable to locate field %s for the LATERALSOURCE statement on line %d\n", Latsource_Descriptor[0]._key, 
			 Prime->LineNumber());
	goto back;
      }
      if ( !Second->Cmp_Head( Latsource_Descriptor[1]._key) ) { // "timeseries"
	if (out) fprintf(out,"Bummer: LATERALSOURCE statement on line %d requires time series specification: %s\n",
			 Prime->LineNumber(), Latsource_Descriptor[1]._key);
	goto back;
      }

      strncpy(node_id, tmp, MAX_WORD_LENGTH);
      loc_index = HASH->Check(node_id);
      if ( loc_index == -1 ) {
	if (out) fprintf(out, "Bummer: cannot find node \"%s\" specified on line %d\n",
			 node_id, Prime->LineNumber());
	goto back;
      }
      
      dba.Reset();
      num_pairs = read_2d_arrays(Second, TS_Descriptor, &dba, 1, out);
      if ( num_pairs <= 0 ) {
	if (out) fprintf(out,"Bummer: error reading 2D data specified on line %d\n", Second->LineNumber() );
	goto back;
      }
      // ready to insert lateral source, with loc_index and time series in dba (good),
      // remember dba.Scale()
      XX = dba.X();
      YY = dba.Y();
      src_id = SUB->MakeSource(num_pairs, &XX[0], &YY[0], dba.Scale(), (OPT.UseMetric()==0?OPT.F3toM3():1.0) );
      if (src_id<0) {
	if (out) fprintf(out,"Bummer: problem with LATERALSOURCE at node \"%s\" on line %d\n",
			 node_id, Prime->LineNumber());
	goto back;
      }

      if ( lsources[ loc_index ] > -1 ) {
	if (out) fprintf(out, "Bummer: duplicated definitino of LATERALSOURCE at node \"%s\"\n",
			 node_id);
	goto back;
      }
      lsources[ loc_index ] = src_id;

      break;

    case p_boundarycondition:

      if (!Second->HasContent()) {
	if (out) fprintf(out,"Bummer: BOUNDARYCONDITION statement on line %d requires a time series specification\n", Prime->LineNumber() );
	goto back;
      }
      good = Prime->Separate(out);
      good = Second->Separate(out);
      if (good<0) {
	if (out) fprintf(out,"Bummer: syntax error in BoundaryCondition Statement in line %d\n", Prime->LineNumber());
	goto back;
      }

      tmp = Prime->Find_Value( Bdn_Descriptor[1]._key); // "type" 
      if (!tmp) {
	if (out) fprintf(out, "Bummer: unable to locate field %s for the BOUNDARYCONDITION statement on line %d\n", Bdn_Descriptor[1]._key, 
			 Prime->LineNumber());
	goto back;
      }
      if ( cmp_string(tmp, BdnType_Descriptor[0]._key) ) { // "AREA"
	bnd_is_area = 1;
      } else if (cmp_string(tmp, BdnType_Descriptor[1]._key) ) { // "DEPTH"
	bnd_is_area = 0;
      } else {
	if (out) fprintf(out, "Bummer: BoundaryCondition has to be either \"%s\" or \"%s\" for statement on line %d\n",
			 BdnType_Descriptor[0]._key, 
			 BdnType_Descriptor[1]._key,
			 Prime->LineNumber() );
	goto back;
      }
      
      tmp = Prime->Find_Value( Bdn_Descriptor[0]._key); // "location"
      if (!tmp) {
	if (out) fprintf(out, "Bummer: unable to locate field %s for the BOUNDARYCONDITION statement on line %d\n", Bdn_Descriptor[0]._key, 
			 Prime->LineNumber());
	goto back;
      }

      strncpy(node_id, tmp, MAX_WORD_LENGTH);
      loc_index = HASH->Check(node_id);
      if ( loc_index == -1 ) {
	if (out) fprintf(out, "Bummer: cannot find node \"%s\" specified on line %d\n",
			 node_id, Prime->LineNumber());
	goto back;
      }
      
      if ( !Second->Cmp_Head( Bdn_Descriptor[2]._key) ) { // "timeseries"
	if (out) fprintf(out,"Bummer: BOUNDARYCONDITION statement on line %d requires time series specification: %s\n",
			 Prime->LineNumber(), Bdn_Descriptor[2]._key);
	goto back;
      }

      dba.Reset();
      num_pairs = read_2d_arrays(Second, TS_Descriptor, &dba, 1, out);
      if ( num_pairs <= 0 ) {
	if (out) fprintf(out,"Bummer: error reading 2D data specified on line %d\n", Second->LineNumber() );
	goto back;
      }

      // ready to insert Bdn condition, with loc_index and time series in dba (good),
      // remember dba.Scale()
      XX = dba.X();
      YY = dba.Y();
      if ( bnd_is_area == 0 ) {
	node = SUB->GetNode( loc_index );
	if ( !node ) {
	  if (out) fprintf(out, "Bummer: node \"%s\" not yet defined!\n", node_id);
	  goto back;
	}
      }
      if ( bnd_is_area) {
	src_id = SUB->MakeSource(num_pairs, &XX[0], &YY[0], dba.Scale(), (OPT.UseMetric()==0?OPT.F2toM2():1.0) );
      } else {
	FlexVec<double> tmp;
	tmp.size(num_pairs);
	node = SUB->GetNode( loc_index);
	for (int jj=0; jj<num_pairs;jj++) { 
	  tmp[jj]= node->GetAbyDepth( YY[jj]*(OPT.UseMetric()==0?OPT.FtoM():1.0) );
	}
	src_id = SUB->MakeSource(num_pairs, &XX[0], &tmp[0], dba.Scale(), 1.0);
      }

      if (src_id < 0) {
	if (out) fprintf(out, "Bummer: problem with BoundaryCondition definition on line %d\n", Prime->LineNumber() );
	goto back;
      }
      if ( asources[ loc_index] >-1 ) {
	if (out) fprintf(out, "Bummer: duplicated definitino of BOUNDARYCONDITION at node \"%s\"\n",
			 node_id);
	goto back;
      }
      asources[ loc_index ] = src_id;
      break;

    default: break;

    } // end switch
  }   // while loop, found all qsource, lsources and asources

  // process the rest, segments, junctions
  rc = def_not_found;
  rewind(F);
  line_num = 0;
  while (1) {  
    int up_idx, down_idx;
    int up1_idx, up2_idx;
    double length, coef1, coef2;
    char *tmp;
    Node *fp, *tp;

    rc = search_block(F, &line_num, Spt_Descriptor, DES_SIZE(Spt_Descriptor), Prime, Second, NULL); 
    
    if (rc == def_error) goto back;
    if (rc == def_not_found) break;

    switch ( rc ) {
    case p_segment:
      good = Prime->Separate(out);
      if (good<0) {
	if (out) fprintf(out,"Bummer: syntax error in netlist specification at line %d\n", Prime->LineNumber());
	goto back;
      }

      tmp = Prime->Find_Value( Segment_Descriptor[0]._key); // "up" 
      if ( !tmp) {
	if (out) fprintf(out, "Bummer: SEGMENT statement on line %d requires the \"%s\" field.\n",
			 Prime->LineNumber(), Segment_Descriptor[0]._key);
	goto back;
      }
      up_idx = HASH->Check(tmp);
      if ( up_idx == -1 ) {
	if (out) fprintf(out, "Bummer: cannot find node \"%s\" specified on line %d\n",
			 tmp, Prime->LineNumber());
	goto back;
      }

      tmp = Prime->Find_Value( Segment_Descriptor[1]._key); // "down:
      if ( !tmp) {
	if (out) fprintf(out, "Bummer: SEGMENT statement on line %d requires the \"%s\" field.\n",
			 Prime->LineNumber(), Segment_Descriptor[1]._key);
	goto back;
      }
      down_idx = HASH->Check(tmp);
      if ( down_idx == -1 ) {
	if (out) fprintf(out, "Bummer: cannot find node \"%s\" specified on line %d\n",
			 tmp, Prime->LineNumber());
	goto back;
      }
      tmp = Prime->Find_Value( Segment_Descriptor[2]._key); // "length"
      if ( !tmp ) {
	if (out) fprintf(out, "Bummer: SEGMENT statement on line %d requires the \"%s\" field.\n",
			 Prime->LineNumber(), Segment_Descriptor[2]._key);
	goto back;
      }
      if ( !is_scientific( tmp ) ) {
	if (out) fprintf(out, "Bummer: invalid real value specification on line %d\n",Prime->LineNumber());
	goto back;
      }
      length = atof(tmp);

      // ready to insert segment, use up_idx, down_idx, length, check length > 0!
      if ( length <= 0.0 ) {
	if (out) fprintf(out,"Bummer: found negative or zero length on line %d\n", Prime->LineNumber() );
	goto back;
      }
      if ( length <= OPT.LMin() ) {
	if (out) fprintf(out,"[WW]: segment length on line %d is %.4e, less than preferred minimal %.4e\n",
			 Prime->LineNumber(), length, OPT.LMin());
      }
      if ( length >= OPT.LMax() ) {
	if (out) fprintf(out,"[WW]: segment length on line %d is %.4e, larger than preferred maxium %.4e\n",
			 Prime->LineNumber(), length, OPT.LMax());
      }

      if (OPT.UseMetric() == 0 ) length *= OPT.FtoM();

      fp = SUB->GetNode( up_idx );
      tp = SUB->GetNode( down_idx );
      if (fp == NULL) {
	if (out) fprintf(out,"Bummer: internal error, unable to locate node at index %d for statement on line %d\n", 
			 up_idx, Prime->LineNumber());
	goto back;
      }      
      if (tp == NULL) {
	if (out) fprintf(out,"Bummer: internal error, unable to locate node at index %d for statement on line %d\n", 
			 down_idx, Prime->LineNumber());
	goto back;
      }

      // in case we have a lateral source
      src_id = lsources[up_idx];
      SUB->MakeStvEquation( up_idx, down_idx, length, src_id );

      break;

    case p_junction:
      good = Prime->Separate(out);
      if (good<0) {
	if (out) fprintf(out,"Bummer: syntax error in netlist specification at line %d\n", Prime->LineNumber());
	goto back;
      }
      
      tmp = Prime->Find_Value( Junc_Descriptor[0]._key); // "up1" 
      if (tmp) {
	up1_idx = HASH->Check(tmp);
	if ( up1_idx == -1 ) {
	  if (out) fprintf(out, "Bummer: cannot find node \"%s\" specified on line %d\n",
			   tmp, Prime->LineNumber());
	  goto back;
	}
      } else up1_idx = -1;


      tmp = Prime->Find_Value( Junc_Descriptor[1]._key); // "up2:
      if (tmp) {
	up2_idx = HASH->Check(tmp);
	if ( up2_idx == -1 ) {
	  if (out) fprintf(out, "Bummer: cannot find node \"%s\" specified on line %d\n",
			   tmp, Prime->LineNumber());
	  goto back;
	}
      } else up2_idx = -1;


      tmp = Prime->Find_Value( Junc_Descriptor[2]._key); // "down"
      if ( !tmp) {
	if (out) fprintf(out, "Bummer: JUNCTION statement on line %d requires the \"%s\" field.\n",
			 Prime->LineNumber(), Junc_Descriptor[2]._key);
	goto back;
      }
      down_idx = HASH->Check(tmp);
      if ( down_idx == -1 ) {
	if (out) fprintf(out, "Bummer: cannot find node \"%s\" specified on line %d\n",
			 tmp, Prime->LineNumber());
	goto back;
      }

      tmp = Prime->Find_Value( Junc_Descriptor[3]._key); // "coeff1"
      if (tmp) {
	if ( !is_scientific( tmp ) ) {
	  if (out) fprintf(out, "Bummer: invalid real value specification on line %d\n",Prime->LineNumber());
	  goto back;
	}
	coef1 = atof(tmp);
	if ( coef1 <= 0.0 ) {
	  if (out) fprintf(out, "Bummer: coefficient should be positive on line %d\n",Prime->LineNumber());
	  goto back;
	}
      } else coef1 = -1.0;

      tmp = Prime->Find_Value( Junc_Descriptor[4]._key); // "coeff2"
      if ( tmp) {
	if ( !is_scientific( tmp ) ) {
	  if (out) fprintf(out, "Bummer: invalid real value specification on line %d\n",Prime->LineNumber());
	  goto back;
	}
	coef2 = atof(tmp);
	if ( coef2 <= 0.0 ) {
	  if (out) fprintf(out, "Bummer: coefficient should be positive on line %d\n",Prime->LineNumber());
	  goto back;
	}
      } else coef2 = -1.0;

      // ready to insert junction, use up1_idx, up2_idx, down_idx, coef1, coef2, check
      if ( up1_idx == -1 && up2_idx == -1 ) {
	if (out) fprintf(out,"Bummer: at least one upstream nodes has to be specified on line %d\n",
			 Prime->LineNumber() );
	goto back;
      }

      if ( coef1 < 0 && coef2 < 0 ) {
	if (out) fprintf(out,"Bummer: at least one upstream coefficients has to be specified on line %d\n",
			 Prime->LineNumber() );
	goto back;
      }

      if ( (up1_idx > 0 && coef1 < 0) || ( up2_idx>0 && coef2<0 ) ) {
	if (out) fprintf(out,"Bummer: mismatch in upstream node and coefficient specifications on line %d\n",
			 Prime->LineNumber());
	goto back;
      }

      /* To add: 
	 distance check among three nodes, use X() and Y() of each node 
       */
      int nn[2];
      double rr[2];

      if ( up1_idx > 0 && up2_idx > 0 ) {  // both
	nn[0] = up1_idx; 
	nn[1] = up2_idx;
	rr[0] = coef1;
	rr[1] = coef2;
	SUB->MakeDepEquation( down_idx, 2, &nn[0], &rr[0]);

      } else if ( up1_idx > 0 ) {    // up1 only
	nn[0] = up1_idx;
	rr[0] = coef1;
	SUB->MakeDepEquation( down_idx, 1, &nn[0], &rr[0]);

      } else {    // up2 only
	nn[0] = up2_idx;
	rr[0] = coef2;
	SUB->MakeDepEquation( down_idx, 1, &nn[0], &rr[0]);

      }

      break;

    default:
      break;
    }
  }
  
  // insert Qsrc, lateral source and Bdn
  for (int jj=0; jj<STAT.N_Nodes(); jj++) {
    if ( qsources[jj] > -1) {
      if ( SUB->GetSource( qsources[jj])->GetParent() >= 0 ) {
	if (out) fprintf(out, "Bummer: trying to re-use qsource at node index %d\n",jj);
	goto back;
      }
      SUB->MakeQrSrcEquation( jj, qsources[jj] );
    }
  }

  
  for (int jj=0; jj<STAT.N_Nodes(); jj++) {
    if ( asources[jj] > -1 ) {
      if ( SUB->GetSource( asources[jj] )->GetParent() >= 0 ) {
	if (out) fprintf(out, "Bummer: trying to re-use asource at node index %d\n",jj);
	goto back;
      }
      SUB->MakeArSrcEquation( jj, asources[jj]);
      break;    // we assume there is only ONE BdnCondition
    }
  }

  r_code = 0; // only at this point we indicate everything is clean

  // calculate the chksum in case we are going to load something from the data
  for (int jj=0; jj<STAT.N_Nodes(); jj++) {
    mychk.add_string( NODE_NAMES->Get(jj) );
  }

  for (int jj=0; jj<STAT.N_Nodes(); jj++) {
    if ( qsources[jj] > -1 ) {
      Source *s = (Source*)SUB->GetSource( qsources[jj] );
      sprintf(chktmp, "%+.1e", s->Evaluate(0.0));
      mychk.add_string(chktmp);
    }
  }
  for (int jj=0; jj<STAT.N_Nodes(); jj++) {
    if ( asources[jj] > -1 ) {
      Source *s = (Source*)SUB->GetSource( asources[jj]);
      sprintf(chktmp, "%+.1e", s->Evaluate(0.0));
      mychk.add_string(chktmp);
    }
  }
  for (int jj=0; jj<STAT.N_Nodes(); jj++) {
    if ( lsources[jj] > -1 ) {
      Source *s = (Source*)SUB->GetSource( lsources[jj] );
      sprintf(chktmp, "%+.1e", s->Evaluate(0.0));
      mychk.add_string(chktmp);
    }
  }
  
  STAT.SetChkSum( mychk.HexCode() );

 back:
  if (Prime) delete Prime;
  if (Second) delete Second;

  return r_code;
}
コード例 #11
0
ファイル: new_parser.C プロジェクト: calebbuahin/SPRNT
FirstDef search_block(FILE *fp, int *cur_ln, Descriptor *des, int sz, StrBuffer *p, StrBuffer *s, FILE *out) {
  int state;
  FirstDef found_key=def_not_found;
  int rc_end, rc_def;
  int ln_number=*cur_ln;

  char tmpbuf[1024];
  char *pt;
  const char def[]="DEF";
  const char end[]="END";

  /* simple state 
     state = 0; nothing, or get ready to return
     state = 1; found first def, everything goes into first buffer
     state = 2; found 2nd def, everthing goes into 2nd buffer
  */
  state = 0;
  found_key = def_not_found;

  p->Reset();
  s->Reset();

  while ( (fgets(tmpbuf, MAX_LINE_LENGTH, fp)) != NULL) {  
    ln_number++;
    if ( tmpbuf[0]=='#'||tmpbuf[0]=='*'||tmpbuf[0]=='%') continue; /* comments */

    pt = strtok(tmpbuf, P_DELIM);
    while (pt!=NULL) {

      rc_end = cmp_string(pt, end);
      rc_def = cmp_string(pt, def);

      if (rc_end == 1) {  /* found "end" */
	state--;
	if ( state < 0 ) {
	  if (out) fprintf(out,"Bummer: redundent END statement on line %d\n",
			   ln_number);
	  return def_error;
	} else if ( state == 0 ) {

	  if (found_key < def_not_found) {
	    p->Finish();
	    s->Finish();
	    *cur_ln = ln_number;
	    return(found_key);
	  }
	}

      } else if ( rc_def == 1 ) { /* found "def" */
	state++;
	if ( state == 1 )      p->Ready(ln_number);
	else if ( state == 2 ) s->Ready(ln_number);
	else if ( state > 2 ) {
	  if (out) fprintf(out,"Bummer: multiple defined DEF on line %d, did you forget an END statement?\n",
			   ln_number);
	  return def_error;
	}

      } else {   /* found something else */

	if ( state ==1 && found_key==def_not_found ) {
	  found_key = decipher_keyword(pt, des, sz);
	}

	if ( found_key < def_not_found ) {
	  if (state==1)          p->Copy_add_Space(pt);
	  else if ( state == 2 ) s->Copy_add_Space(pt);
	} else { // we found something we don't recognize
	  if (out) fprintf(out,"Bummer: Don't know how to deciper DEF \"%s\" on line %d\n",
			   pt, ln_number);
	  return (def_error);
	}
      }

      /* get the next token */
      pt=strtok(NULL, P_DELIM);
    }
  }

  // at this point, state should be zero!
  if ( state != 0 ) {
    if (out) fprintf(out,"Bummer: unbalanced DEF and END statements\n");
    found_key = def_error;
  }

  *cur_ln = ln_number;
  return (found_key);
}