Ejemplo n.º 1
0
static void getq(void) {
  int cq=cc;
  int i=0;
  for(;;) {
    getcc();
    if(cc==cq) {
      if(i!=0&&value[i-1]=='\\') --i; else {getcc(); break;}
    } else if(cc<' ') {error(ARX_ER_NOQ); break;}
    value[i++]=cc;
    if(i==len_v) value=(char*)m_stretch(value,len_v=2*i,i,sizeof(char));
  }
  value[i]='\0';
}
Ejemplo n.º 2
0
static void getrng(void) {
  int ircur=-1,i=0;
  int cc0;
  for(;;) {
    cc0=cc; getcc();
    if(cc=='}') ircur=i;
    else if(cc=='>') {if(cc0=='=') {getcc(); break;}} /* use => as terminator */
    else if(cc==-1) {error(ARX_ER_EXP,"=>",sym2str(SYM_EOF)); break;}
    value[i++]=cc;
    if(i==len_v) value=(char*)m_stretch(value,len_v=2*i,i,sizeof(char));
  }
  if(ircur==-1) {error(ARX_ER_EXP,sym2str(SYM_RCUR),sym2str(SYM_EOF)); ircur=0;}
  value[ircur]='\0';
}
Ejemplo n.º 3
0
static int getid(void) {
  if(nmtoken(cc)) {
    int i=0;
    do {
      value[i++]=cc;
      if(i==len_v) value=(char*)m_stretch(value,len_v=2*i,i,sizeof(char));
      getcc();
    } while(nmtoken(cc));
    value[i]='\0';
    return 1;
  } else return 0;
}
Ejemplo n.º 4
0
Archivo: lex.c Proyecto: lufia/wf
int
yylex(void)
{
	int c, r;
	char c1;
	Sym *s;

genblock:
	if(block != nblock){
		if(block > nblock){
			if(debug)
				fprint(2, "%s %d -> %d\n", ty(Tend), block, nblock);
			block--;
			return Tend;
		}else{
			if(debug)
				fprint(2, "%s %d -> %d\n", ty(Tbegin), block, nblock);
			block++;
			return Tbegin;
		}
	}

	c = GETC();
	if(c == Beof){
		nblock = 0;
		if(block != nblock)
			goto genblock;
		return 0;
	}
	UNGETC(c);

	switch(state){
	case Head0:			/* [%type] string */
		c = GETC();
		if(c != '%'){
			UNGETC(c);
			setstate(Body0);
			goto genblock;
		}
		r = readname(" \t");
		if(r == Terror)
			return fail(Head2);

		s = lookup(s_to_c(sbuf));
		yylval.sym = s;
		if(debug)
			fprint(2, "Sym[%s] %s\n", ty(s->type), s->name);
		setstate(Head1);
		return s->type;

	case Head1:			/* %type [string] */
		r = readstr("\n", " \t", 0);
		if(r == Terror)
			return fail(Head2);
		yylval.s = estrdup(s_to_c(sbuf));
		if(debug)
			fprint(2, "%s %q\n", ty(Tstring), yylval.s);
		setstate(Head2);
		return Tstring;

	case Head2:
		skip(" \t");
		c = GETC();
		assert(c == '\n' || c == Beof);
		setstate(Head0);
		return ';';

	case Body0:			/* [indent] cmd inline */
		c = GETC();
		if(c == '%'){
			UNGETC(c);
			setstate(Head0);
			goto genblock;
		}
		UNGETC(c);

		r = skip(" \t");
		c = GETC();
		if(c == '\n'){
			if(debug)
				fprint(2, "%s\n", ty(Tbreak));
			return Tbreak;
		}
		UNGETC(c);

		nblock = r;
		setstate(Body1);
		goto genblock;

	case Body1:			/* indent [cmd] inline */
		switch(c = GETC()){
		case Beof:
			yyerror("eof in body");
			if(debug)
				fprint(2, "%s\n", ty(Terror));
			return fail(Body3);
		case '=':
		case '\\':
		case '+':
		case '*':
		case ':':
		case '-':
		case '>':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Body2);
			return c;
		case '!':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Code);
			return c;
		case '{':
		case '}':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Body3);
			return c;
		case '#':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(ID);
			return c;
		case '.':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Class);
			return c;
		case '|':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Table);
			return c;
		default:
			UNGETC(c);
			if(debug)
				fprint(2, "\\\n");
			setstate(Body2);
			return '\\';
		}

	case Body2:			/* indent cmd [inline] */
	case Table:
		r = skip(" \t");
		if(state == Table && r > 0)
			return ',';

		switch(c = getcc(&c1, "*[]|<>")){
		case Beof:
			yyerror("eof in body");
			if(debug)
				fprint(2, "%s\n", ty(Terror));
			return fail(Body3);
		case '\n':
			UNGETC(c);
			setstate(Body3);
			break;
		case '*':
		case '[':
		case ']':
		case '|':
		case '<':
		case '>':
			if(c == '[' || c == '|' || c == '<')
				skip(" \t\n");
			if(debug)
				fprint(2, "%c\n", c);
			return c;
		default:
			s_reset(sbuf);
			s_putc(sbuf, c1);
			while((c=getcc(&c1, "*[]|<>")) == 0){
				if(state == Table && c1 == '\t'){
					UNGETC(c);
					break;
				}
				s_putc(sbuf, c1);
			}
			s_terminate(sbuf);
			if(c > 0)
				UNGETC(c);
			yylval.s = estrdup(s_to_c(sbuf));
			if(debug)
				fprint(2, "%s %q\n", ty(Tstring), yylval.s);
			return Tstring;
		}

	case Body3:
		skip(" \t");
		c = GETC();
		if(c != '\n')
			return fail(Body3);
		setstate(Body0);
		return ';';

	case Code:
		r = readstr("\n", "", 1);
		if(r == Terror){
			if(debug)
				fprint(2, "%s\n", ty(Terror));
			return fail(Body3);
		}
		setstate(Body3);
		yylval.s = estrdup(s_to_c(sbuf));
		if(debug)
			fprint(2, "%s %q\n", ty(Tstring), yylval.s);
		return Tstring;

	case ID:
	case Class:
		r = readname(" \t");
		if(r == Terror){
			if(debug)
				fprint(2, "%s\n", ty(Terror));
			return fail(Body3);
		}
		setstate(Body3);
		yylval.s = estrdup(s_to_c(sbuf));
		if(debug)
			fprint(2, "%s %q\n", ty(Tstring), yylval.s);
		return Tstring;

	default:
		assert(0);
		return Terror;
	}
}
Ejemplo n.º 5
0
void getenc(encoding ev, int width[256])
{  int i, SCMseen, Ccnt, wx, cc;
   FILE *afm;
   char *name, ns;
   
   for (i=0; i < 256; i++) { ev[i] = NULL; width[i] = -1000; }
   if (encfile) {
      enc = fopen(encfile, "r");
      if (enc == NULL) fatal("Can't open %s\n", encfile);
      if (nextsymbol() != '/') fatal("missing '/encoding' in %s\n", encfile);
      if (nextsymbol() != '[') fatal("missing '[' in %s\n", encfile);
      i = 0;
      while (i < 256 && (ns = nextsymbol()) == '/') {
         name = string(pline);
         if (strcmp(name, ".notdef") == 0) { 
            i++; remove_string();
            continue; 
         }
         addcc(name, i++);
      }
      if (i != 256) fatal("missing %d symbols in %s\n", 256-i, encfile);
      if (nextsymbol() != ']') fatal("missing ']' in %s\n", encfile);
      fclose(enc);
   }
   afm = fopen(afmfile, "r");
   if (afm == NULL) fatal("Can't open %s\n", afmfile);
   SCMseen = 0; Ccnt = 0;
   while (fgets(line, LINEBUF-1, afm))
      if (strncmp(line, "StartCharMetrics", 16) == 0)
      { SCMseen = 1; break; }
   if (SCMseen == 0) fatal("%s: no valid AFM file\n", afmfile);
   while (fgets(line, LINEBUF-1, afm)) {
      if (strncmp(line, "EndCharMetrics", 14) == 0) break;
      if (strncmp(line, "C ", 2) != 0) 
         fatal("%s: unexpected line\n", afmfile);

      /* Gracefully terminate when the AFM file is not valid.  Every line */
      /* in the AFM file should specify a "C"haracter, a "WX"idth, and    */
      /* a "N"ame. (ndw)
      */
      pline = value_after(line, "C"); 
      if (pline == NULL)
         fatal("\nBad char metric in %s (no char):\n\t %s\n", afmfile, line);
      cc = decimal(pline);
      pline = value_after(pline, "WX"); 
      if (pline == NULL)
         fatal("\nBad char metric in %s (no width):\n\t %s\n", afmfile, line);
      wx = decimal(pline);
      pline = value_after(pline, "N"); 
      if (pline == NULL)
         fatal("\nBad char metric in %s (no name):\n\t %s\n", afmfile, line);
      name = string(pline);
      
      if (encfile) {
         if ((i = getcc(name)) == -1) {
            remove_string();
            continue;
	 }
         do { /* allow more occurences per name */
            ev[i] = name; width[i] = wx;
            i = getcc(name);
         }
         while (i >= 0);
      }
      else if (cc >= 0 && cc <= 255) { /* ndw: 10/13/92 */
	 ev[cc] = name; width[cc] = wx;
      }
      else if (cc > 255)
	 printf("Char code %d ignored (out of range).\n", cc);
      Ccnt++;
   }
   if (Ccnt == 0) fatal("%s: no characters selected\n", afmfile);   
}
Ejemplo n.º 6
0
void orcc()
{
  setcc(getcc() | FETCHB);
}
Ejemplo n.º 7
0
void cwai()
{
  setcc((getcc() & get_i8()) | 0x80);
}
Ejemplo n.º 8
0
void andc()
{
  setcc(getcc() & FETCHB);
}
Ejemplo n.º 9
0
/*
 * Main command processor.
 * Accept and execute commands until a quit command, then return.
 */
void
commands(void)
{
	int c, action;

	last_mca = 0;
	nscroll = (sc_height + 1) / 2;

	for (;;) {
		mca = 0;
		number = 0;

		/*
		 * See if any signals need processing.
		 */
		if (sigs) {
			psignals();
			if (quitting)
				quit();
		}
		/*
		 * Display prompt and accept a character.
		 */
		CMD_RESET;
		if (!prompt()) {
			next_file(1);
			continue;
		}
		noprefix();
		c = getcc();

again:		if (sigs)
			continue;

		/*
		 * If we are in a multicharacter command, call mca_char.
		 * Otherwise we call cmd_decode to determine the
		 * action to be performed.
		 */
		if (mca)
			switch (mca_char(c)) {
			case MCA_MORE:
				/*
				 * Need another character.
				 */
				c = getcc();
				goto again;
			case MCA_DONE:
				/*
				 * Command has been handled by mca_char.
				 * Start clean with a prompt.
				 */
				continue;
			case NO_MCA:
				/*
				 * Not a multi-char command
				 * (at least, not anymore).
				 */
				break;
			}

		/* decode the command character and decide what to do. */
		switch (action = cmd_decode(c)) {
		case A_DIGIT:		/* first digit of a number */
			start_mca(A_DIGIT, ":");
			goto again;
		case A_F_SCREEN:	/* forward one screen */
			CMD_EXEC;
			if (number <= 0 && (number = sc_window) <= 0)
				number = sc_height - 1;
			forward(number, 1);
			break;
		case A_B_SCREEN:	/* backward one screen */
			CMD_EXEC;
			if (number <= 0 && (number = sc_window) <= 0)
				number = sc_height - 1;
			backward(number, 1);
			break;
		case A_F_LINE:		/* forward N (default 1) line */
			CMD_EXEC;
			forward(number <= 0 ? 1 : number, 0);
			break;
		case A_B_LINE:		/* backward N (default 1) line */
			CMD_EXEC;
			backward(number <= 0 ? 1 : number, 0);
			break;
		case A_F_SCROLL:	/* forward N lines */
			CMD_EXEC;
			if (number > 0)
				nscroll = number;
			forward(nscroll, 0);
			break;
		case A_B_SCROLL:	/* backward N lines */
			CMD_EXEC;
			if (number > 0)
				nscroll = number;
			backward(nscroll, 0);
			break;
		case A_FREPAINT:	/* flush buffers and repaint */
			if (!ispipe) {
				ch_init(0, 0);
				clr_linenum();
			}
			/* FALLTHROUGH */
		case A_REPAINT:		/* repaint the screen */
			CMD_EXEC;
			repaint();
			break;
		case A_GOLINE:		/* go to line N, default 1 */
			CMD_EXEC;
			if (number <= 0)
				number = 1;
			jump_back(number);
			break;
		case A_PERCENT:		/* go to percent of file */
			CMD_EXEC;
			if (number < 0)
				number = 0;
			else if (number > 100)
				number = 100;
			jump_percent(number);
			break;
		case A_GOEND:		/* go to line N, default end */
			CMD_EXEC;
			if (number <= 0)
				jump_forw();
			else
				jump_back(number);
			break;
		case A_STAT:		/* print file name, etc. */
			longprompt = 1;
			continue;
		case A_QUIT:		/* exit */
			quit();
		case A_F_SEARCH:	/* search for a pattern */
		case A_B_SEARCH:
			if (number <= 0)
				number = 1;
			start_mca(action, (action==A_F_SEARCH) ? "/" : "?");
			last_mca = mca;
			wsearch = 1;
			c = getcc();
			if (c == '!') {
				/*
				 * Invert the sense of the search; set wsearch
				 * to 0 and get a new character for the start
				 * of the pattern.
				 */
				start_mca(action, 
				    (action == A_F_SEARCH) ? "!/" : "!?");
				wsearch = 0;
				c = getcc();
			}
			goto again;
		case A_AGAIN_SEARCH:		/* repeat previous search */
			if (number <= 0)
				number = 1;
			if (wsearch)
				start_mca(last_mca, 
				    (last_mca == A_F_SEARCH) ? "/" : "?");
			else
				start_mca(last_mca, 
				    (last_mca == A_F_SEARCH) ? "!/" : "!?");
			CMD_EXEC;
			(void)search(mca == A_F_SEARCH, (char *)NULL,
			    number, wsearch);
			break;
		case A_HELP:			/* help */
			lower_left();
			clear_eol();
			fputs("help", stdout);
			CMD_EXEC;
			help();
			break;
		case A_TAGFILE:			/* tag a new file */
			CMD_RESET;
			start_mca(A_TAGFILE, "Tag: ");
			c = getcc();
			goto again;
		case A_FILE_LIST:		/* show list of file names */
			CMD_EXEC;
			showlist();
			repaint();
			break;
		case A_EXAMINE:			/* edit a new file */
			CMD_RESET;
			start_mca(A_EXAMINE, "Examine: ");
			c = getcc();
			goto again;
		case A_VISUAL:			/* invoke the editor */
			if (ispipe) {
				error("Cannot edit standard input");
				break;
			}
			CMD_EXEC;
			editfile();
			ch_init(0, 0);
			clr_linenum();
			break;
		case A_NEXT_FILE:		/* examine next file */
			if (number <= 0)
				number = 1;
			next_file(number);
			break;
		case A_PREV_FILE:		/* examine previous file */
			if (number <= 0)
				number = 1;
			prev_file(number);
			break;
		case A_SETMARK:			/* set a mark */
			lower_left();
			clear_eol();
			start_mca(A_SETMARK, "mark: ");
			c = getcc();
			if (c == erase_char || c == kill_char)
				break;
			setmark(c);
			break;
		case A_GOMARK:			/* go to mark */
			lower_left();
			clear_eol();
			start_mca(A_GOMARK, "goto mark: ");
			c = getcc();
			if (c == erase_char || c == kill_char)
				break;
			gomark(c);
			break;
		case A_PREFIX:
			/*
			 * The command is incomplete (more chars are needed).
			 * Display the current char so the user knows what's
			 * going on and get another character.
			 */
			if (mca != A_PREFIX)
				start_mca(A_PREFIX, "");
			if (CONTROL_CHAR(c)) {
				putchar('^');
				c = CARAT_CHAR(c);
			}
			putchar(c);
			c = getcc();
			goto again;
		default:
			putchar('\7');
			break;
		}
	}
}
Ejemplo n.º 10
0
static void getsym(void) {
  for(;;) {
    if(0<=cc&&cc<=' ') {getcc(); continue;}
    switch(cc) {
    case -1: sym=SYM_EOF; return;
    case '#': do getcc(); while(cc!='\n'&&cc!='\r'); getcc(); continue;
    case '{':
      if(sym==SYM_VALD||sym==SYM_NVAL) {
	getrng(); sym=SYM_RENG;
      } else {
	getcc(); sym=SYM_LCUR;
      }
      return;
    case '}': getcc(); sym=SYM_RCUR; return;
    case '!': getcc();
      if(cc=='~') {
	getcc(); sym=SYM_NMTC;
      } else {
	if(getid()) {
	  if(strcmp("valid",value)!=0) {error(ARX_ER_EXP,sym2str(SYM_NVAL),value);} sym=SYM_NVAL;
	} else {error(ARX_ER_SYN); sym=SYM_INVL;}
      }
      return;
    case '=': getcc();
      switch(cc) {
      case '~': getcc(); sym=SYM_MTCH; return;
      case '>': getcc(); if(sym!=SYM_RGXP) error(ARX_ER_SYN); continue;
      default: sym=SYM_ASGN; return;
      }
    case '"': getq(); sym=SYM_LTRL; return;
    case '/': getq(); sym=SYM_RGXP; return;
    default:
      if(getid()) {
	sym=strcmp("grammars",value)==0?SYM_GRMS
	 : strcmp("valid",value)==0?SYM_VALD:SYM_IDNT;
      } else {getcc(); error(ARX_ER_SYN); sym=SYM_INVL;}
      return;
    }
  }
}
Ejemplo n.º 11
0
//================================================================================
const tensor& DM04_PF::Dm_Dkin2(const stresstensor &Stre, 
                          const straintensor &Stra, 
                          const MaterialParameter &MaterialParameter_in) const
{
    const double oneOver3 = 1.0/3.0;
    const double rt23 = sqrt(2.0/3.0);
    
    tensor I2("I", 2, def_dim_2);    

    double e0 = gete0(MaterialParameter_in);
    double e_r = gete_r(MaterialParameter_in);
    double lambda_c = getlambda_c(MaterialParameter_in);
    double xi = getxi(MaterialParameter_in);
    double Pat = getPat(MaterialParameter_in);
    //double m = getm(MaterialParameter_in);
    double M_cal = getM_cal(MaterialParameter_in);
    double cc = getcc(MaterialParameter_in);
    double A0 = getA0(MaterialParameter_in);
    double nd = getnd(MaterialParameter_in);    

    stresstensor alpha = getalpha(MaterialParameter_in);
    stresstensor z = getz(MaterialParameter_in);

    stresstensor n;
    stresstensor alpha_d;
    stresstensor alpha_d_alpha;
    double g = 0.0;
    double ec = e_r;
    double stateParameter = 0.0;
    double expnd = 1.0;
    //double ad = 0.0;
    double D0 = 0.0;
    stresstensor s_bar;
    double norm_s = 0.0;
    double epsilon_v = 0.0;
    double e = e0;
    double J3D;
    double cos3theta = 0.0;
    double z_n = 0.0;
    double alpha_n = 0.0;
    double s_n = 0.0;

    double p = Stre.p_hydrostatic();
    stresstensor s = Stre.deviator();
            
    s_bar = s - (alpha *p);
    norm_s = sqrt( (s_bar("ij")*s_bar("ij")).trace() );
    if (p > 0.0 && norm_s > 0.0)
        n = s_bar * (1.0/norm_s);
       
    J3D = n.Jinvariant3();
    cos3theta = -3.0*sqrt(6.0) *J3D;
    
    if (cos3theta > 1.0) 
      cos3theta = 1.0;

    if (cos3theta < -1.0) 
      cos3theta = -1.0;
    
    g = getg(cc, cos3theta);

    if ( (p/Pat) >= 0.0 )
      ec = getec(e_r, lambda_c, xi, Pat, p);
    
    epsilon_v = Stra.Iinvariant1();
    e = e0 + (1.0 + e0) *epsilon_v;
    
    stateParameter = e - ec;    
    expnd = exp(nd*stateParameter);
    
    alpha_n = (alpha("ij")*n("ij")).trace();
    s_n = (s("ij")*n("ij")).trace();

    // way 1
    //ad = g*M_cal*expnd - m;
    //D0 = rt23 * ad - alpha_n;

    // way 2
    D0 = rt23*g*M_cal*expnd - s_n /p;

    tensor dD_dz(2, def_dim_2, 0.0);

    // dD_dz:
    if (z_n > 0.0)
      dD_dz = n *A0;

    // dm_da:
    tensor tensor1 = I2("ij")*dD_dz("mn");
      tensor1.null_indices();
    
    PlasticFlow::PF_tensorR4 = tensor1 *(-D0*oneOver3);   
    
    return PlasticFlow::PF_tensorR4;
}
Ejemplo n.º 12
0
//================================================================================
const tensor& DM04_PF::Dm_Dkin(const stresstensor &Stre, 
                          const straintensor &Stra, 
                          const MaterialParameter &MaterialParameter_in) const
{
    const double oneOver3 = 1.0/3.0;
    const double rt23 = sqrt(2.0/3.0);

    tensor I2("I", 2, def_dim_2);    
    tensor I4 = I2("ij")*I2("kl");
    tensor I4s = ( I4.transpose0110() + I4.transpose0111() ) *0.5;

    double e0 = gete0(MaterialParameter_in);
    double e_r = gete_r(MaterialParameter_in);
    double lambda_c = getlambda_c(MaterialParameter_in);
    double xi = getxi(MaterialParameter_in);
    double Pat = getPat(MaterialParameter_in);
    //double m = getm(MaterialParameter_in);
    double M_cal = getM_cal(MaterialParameter_in);
    double cc = getcc(MaterialParameter_in);
    double A0 = getA0(MaterialParameter_in);
    double nd = getnd(MaterialParameter_in);    

    stresstensor alpha = getalpha(MaterialParameter_in);
    stresstensor z = getz(MaterialParameter_in);

    stresstensor n;
    stresstensor alpha_d;
    stresstensor alpha_d_alpha;
    double g = 0.0;
    double ec = e_r;
    double stateParameter = 0.0;
    double expnd = 1.0;
    //double ad = 0.0;
    double A_d = 0.0;
    double B = 1.0;
    double C = 0.0;
    double D0 = 0.0;
    stresstensor s_bar;
    double norm_s = 0.0;
    double epsilon_v = 0.0;
    double e = e0;
    double J3D;
    double cos3theta = 0.0;
    double z_n = 0.0;
    double alpha_n = 0.0;
    double s_n = 0.0;

    double p = Stre.p_hydrostatic();
    stresstensor s = Stre.deviator();
            
    s_bar = s - (alpha *p);
    norm_s = sqrt( (s_bar("ij")*s_bar("ij")).trace() );
    if (p > 0.0 && norm_s > 0.0)
        n = s_bar * (1.0/norm_s);
       
    J3D = n.Jinvariant3();
    cos3theta = -3.0*sqrt(6.0) *J3D;
    
    if (cos3theta > 1.0) 
      cos3theta = 1.0;

    if (cos3theta < -1.0) 
      cos3theta = -1.0;
    
    g = getg(cc, cos3theta);

    if ( (p/Pat) >= 0.0 )
      ec = getec(e_r, lambda_c, xi, Pat, p);
    
    epsilon_v = Stra.Iinvariant1();
    e = e0 + (1.0 + e0) *epsilon_v;
    
    stateParameter = e - ec;    
    expnd = exp(nd*stateParameter);
    
    alpha_n = (alpha("ij")*n("ij")).trace();
    s_n = (s("ij")*n("ij")).trace();

    // way 1
    //ad = g*M_cal*expnd - m;
    //D0 = rt23 * ad - alpha_n;

    // way 2
    D0 = rt23*g*M_cal*expnd - s_n /p;

    z_n = (z("ij")*n("ij")).trace();
    if (z_n < 0.0) 
      z_n = 0.0;
    A_d = A0 * (1.0 + z_n);

    B = 1.0 + 1.5 *((1.0-cc)/cc) *g *cos3theta;
    C = 3.0 *sqrt(1.5) *((1.0-cc)/cc) *g;
    
    tensor n_n = n("ik")*n("kj");
      n_n.null_indices();

    tensor nt_nt = n("ij")*n("kl");
      nt_nt.null_indices();

    tensor alpha_I = alpha("ij")*I2("kl");
      alpha_I.null_indices();

    tensor n_I = n("ij")*I2("kl");
      n_I.null_indices();

    // dn_dalpha:
    tensor dn_da = nt_nt - I4s;
    dn_da = dn_da *(p/norm_s);

    // dcos3theta_dalpha:
    tensor dcos3theta_da = dn_da("ijmn")*n_n("ji");
      dcos3theta_da.null_indices();
    dcos3theta_da = dcos3theta_da *(-3.0*sqrt(6.0));

    // dg_da:
    tensor dg_da = dcos3theta_da *(g*g*(1.0-cc)/(2.0*cc));

    // dB_da:
    tensor dB_da = (dg_da*cos3theta + dcos3theta_da*g) *(1.5*(1.0-cc)/cc);

    // dC_ds:
    tensor dC_da = dg_da *(3.0*sqrt(1.5)*(1.0-cc)/cc);

    // dR_da:
    tensor tensor1 = n("ij")*dB_da("mn");
      tensor1.null_indices();
    tensor tensor2 = n_n - I2 *oneOver3;
    tensor tensor3 = tensor2("ij")*dC_da("mn");
      tensor3.null_indices();
    tensor tensor4 = n("kj")*dn_da("ikmn");
      tensor4.null_indices();
    tensor4.transpose1100(); 
    tensor dR_da = dn_da *B + tensor1 + tensor4 *(2.0*C) + tensor3;

    // dad_da:
    tensor dad_da = dg_da *(M_cal*expnd);

    // dD_da:
    
    // way 1
    //tensor tensor5 = alpha("pq")*dn_da("pqmn");
    //  tensor5.null_indices();
    //tensor dD_da = (dad_da *rt23 - n - tensor5) *(-A_d);
    
    // way 2
    tensor tensor5 = s("pq")*dn_da("pqmn");
      tensor5.null_indices();
    tensor dD_da = (dad_da *rt23 - tensor5 *(1.0/p)) *(-A_d);

    if (z_n > 0.0) {
      tensor tensor6 = z("pq")*dn_da("pqmn");
        tensor6.null_indices();
      dD_da += tensor6 *(-A0*D0);
    }

    // dm_da:
    tensor tensor7 = I2("ij")*dD_da("mn");
      tensor7.null_indices();
    
    PlasticFlow::PF_tensorR4 = dR_da + tensor7 *oneOver3;   
    
    return PlasticFlow::PF_tensorR4;
}
Ejemplo n.º 13
0
//================================================================================
const straintensor& DM04_PF::PlasticFlowTensor(const stresstensor& Stre, 
                                               const straintensor& Stra, 
                                               const MaterialParameter &MaterialParameter_in) const
{
    const double oneOver3 = 1.0/3.0;
    const double rt23 = sqrt(2.0/3.0);    
    tensor I2("I", 2, def_dim_2);

    double e0 = gete0(MaterialParameter_in);
    double e_r = gete_r(MaterialParameter_in);
    double lambda_c = getlambda_c(MaterialParameter_in);
    double xi = getxi(MaterialParameter_in);
    double Pat = getPat(MaterialParameter_in);
    //double m = getm(MaterialParameter_in);
    double M_cal = getM_cal(MaterialParameter_in);
    double cc = getcc(MaterialParameter_in);
    double A0 = getA0(MaterialParameter_in);
    double nd = getnd(MaterialParameter_in);    

    stresstensor alpha = getalpha(MaterialParameter_in);
    stresstensor z = getz(MaterialParameter_in);

    stresstensor n;
    stresstensor alpha_d;
    stresstensor alpha_d_alpha;
    double g = 0.0;
    double ec = e_r;
    double stateParameter = 0.0;
    double expnd = 1.0;
    //double ad = 0.0;
    double A_d = 0.0;
    double B = 1.0;
    double C = 0.0;
    double D = 0.0;
    double D0 = 0.0;
    stresstensor s_bar;
    double norm_s = 0.0;
    double epsilon_v = 0.0;
    double e = e0;
    double J3D;
    double cos3theta = 0.0;
    double z_n = 0.0;
    double alpha_n = 0.0;
    double s_n = 0.0;

    double p = Stre.p_hydrostatic();
    stresstensor s = Stre.deviator();
            
    s_bar = s - (alpha *p);
    norm_s = sqrt( (s_bar("ij")*s_bar("ij")).trace() );
    if (p > 0.0 && norm_s > 0.0)
      n = s_bar * (1.0/norm_s);
       
    J3D = n.Jinvariant3();
    cos3theta = -3.0*sqrt(6.0) *J3D;

    if (p <= 0.0)
      cos3theta = 1.0;
    
    if (cos3theta > 1.0) 
      cos3theta = 1.0;

    if (cos3theta < -1.0) 
      cos3theta = -1.0;
    
    g = getg(cc, cos3theta);

    if ( (p/Pat) >= 0.0 )
      ec = getec(e_r, lambda_c, xi, Pat, p);
    
    epsilon_v = Stra.Iinvariant1();
    e = e0 + (1.0 + e0) *epsilon_v;
    
    stateParameter = e - ec;    
    expnd = exp(nd*stateParameter);
    
    alpha_n = (alpha("ij")*n("ij")).trace();
    s_n = (s("ij")*n("ij")).trace();

    // way 1
    //ad = g*M_cal*expnd - m;
    //D0 = rt23 *ad - alpha_n;

    // way 2, better use this when "p" is small
    D0 = rt23*g*M_cal*expnd - s_n /p;

    z_n = (z("ij")*n("ij")).trace();
    if (z_n < 0.0) 
      z_n = 0.0;
    A_d = A0 * (1.0 + z_n);

    D = D0 *(-A_d);

    B = 1.0 + 1.5 *((1.0-cc)/cc) *g *cos3theta;
    C = 3.0 *sqrt(1.5) *((1.0-cc)/cc) *g;
    
    stresstensor n_n = n("ik")*n("kj");
      n_n.null_indices();

    // note different 'positive-negative' since we assume extension (dilation) positive 
    // which is different from the Ref.
    DM04_PF::DM04m = n *B + n_n *C + I2 *((D-C)*oneOver3);
                           
    return DM04_PF::DM04m;
}
Ejemplo n.º 14
0
/*
 * Main command processor.
 * Accept and execute commands until a quit command.
 */
void
commands(void)
{
	int c = 0;
	int action;
	char *cbuf;
	int newaction;
	int save_search_type;
	char *extra;
	char tbuf[2];
	PARG parg;
	IFILE old_ifile;
	IFILE new_ifile;
	char *tagfile;

	search_type = SRCH_FORW;
	wscroll = (sc_height + 1) / 2;
	newaction = A_NOACTION;

	for (;;) {
		mca = 0;
		cmd_accept();
		number = 0;
		curropt = NULL;

		/*
		 * See if any signals need processing.
		 */
		if (sigs) {
			psignals();
			if (quitting)
				quit(QUIT_SAVED_STATUS);
		}

		/*
		 * Display prompt and accept a character.
		 */
		cmd_reset();
		prompt();
		if (sigs)
			continue;
		if (newaction == A_NOACTION)
			c = getcc();

again:
		if (sigs)
			continue;

		if (newaction != A_NOACTION) {
			action = newaction;
			newaction = A_NOACTION;
		} else {
			/*
			 * If we are in a multicharacter command, call mca_char.
			 * Otherwise we call fcmd_decode to determine the
			 * action to be performed.
			 */
			if (mca)
				switch (mca_char(c)) {
				case MCA_MORE:
					/*
					 * Need another character.
					 */
					c = getcc();
					goto again;
				case MCA_DONE:
					/*
					 * Command has been handled by mca_char.
					 * Start clean with a prompt.
					 */
					continue;
				case NO_MCA:
					/*
					 * Not a multi-char command
					 * (at least, not anymore).
					 */
					break;
				}

			/*
			 * Decode the command character and decide what to do.
			 */
			if (mca) {
				/*
				 * We're in a multichar command.
				 * Add the character to the command buffer
				 * and display it on the screen.
				 * If the user backspaces past the start
				 * of the line, abort the command.
				 */
				if (cmd_char(c) == CC_QUIT || len_cmdbuf() == 0)
					continue;
				cbuf = get_cmdbuf();
			} else {
				/*
				 * Don't use cmd_char if we're starting fresh
				 * at the beginning of a command, because we
				 * don't want to echo the command until we know
				 * it is a multichar command.  We also don't
				 * want erase_char/kill_char to be treated
				 * as line editing characters.
				 */
				tbuf[0] = (char)c;
				tbuf[1] = '\0';
				cbuf = tbuf;
			}
			extra = NULL;
			action = fcmd_decode(cbuf, &extra);
			/*
			 * If an "extra" string was returned,
			 * process it as a string of command characters.
			 */
			if (extra != NULL)
				ungetsc(extra);
		}
		/*
		 * Clear the cmdbuf string.
		 * (But not if we're in the prefix of a command,
		 * because the partial command string is kept there.)
		 */
		if (action != A_PREFIX)
			cmd_reset();

		switch (action) {
		case A_DIGIT:
			/*
			 * First digit of a number.
			 */
			start_mca(A_DIGIT, ":", (void*)NULL, CF_QUIT_ON_ERASE);
			goto again;

		case A_F_WINDOW:
			/*
			 * Forward one window (and set the window size).
			 */
			if (number > 0)
				swindow = (int)number;
			/* FALLTHRU */
		case A_F_SCREEN:
			/*
			 * Forward one screen.
			 */
			if (number <= 0)
				number = get_swindow();
			cmd_exec();
			if (show_attn)
				set_attnpos(bottompos);
			forward((int)number, 0, 1);
			break;

		case A_B_WINDOW:
			/*
			 * Backward one window (and set the window size).
			 */
			if (number > 0)
				swindow = (int)number;
			/* FALLTHRU */
		case A_B_SCREEN:
			/*
			 * Backward one screen.
			 */
			if (number <= 0)
				number = get_swindow();
			cmd_exec();
			backward((int)number, 0, 1);
			break;

		case A_F_LINE:
			/*
			 * Forward N (default 1) line.
			 */
			if (number <= 0)
				number = 1;
			cmd_exec();
			if (show_attn == OPT_ONPLUS && number > 1)
				set_attnpos(bottompos);
			forward((int)number, 0, 0);
			break;

		case A_B_LINE:
			/*
			 * Backward N (default 1) line.
			 */
			if (number <= 0)
				number = 1;
			cmd_exec();
			backward((int)number, 0, 0);
			break;

		case A_F_SKIP:
			/*
			 * Skip ahead one screen, and then number lines.
			 */
			if (number <= 0) {
				number = get_swindow();
			} else {
				number += get_swindow();
			}
			cmd_exec();
			if (show_attn == OPT_ONPLUS)
				set_attnpos(bottompos);
			forward((int)number, 0, 1);
			break;

		case A_FF_LINE:
			/*
			 * Force forward N (default 1) line.
			 */
			if (number <= 0)
				number = 1;
			cmd_exec();
			if (show_attn == OPT_ONPLUS && number > 1)
				set_attnpos(bottompos);
			forward((int)number, 1, 0);
			break;

		case A_BF_LINE:
			/*
			 * Force backward N (default 1) line.
			 */
			if (number <= 0)
				number = 1;
			cmd_exec();
			backward((int)number, 1, 0);
			break;

		case A_FF_SCREEN:
			/*
			 * Force forward one screen.
			 */
			if (number <= 0)
				number = get_swindow();
			cmd_exec();
			if (show_attn == OPT_ONPLUS)
				set_attnpos(bottompos);
			forward((int)number, 1, 0);
			break;

		case A_F_FOREVER:
			/*
			 * Forward forever, ignoring EOF.
			 */
			newaction = forw_loop(0);
			break;

		case A_F_UNTIL_HILITE:
			newaction = forw_loop(1);
			break;

		case A_F_SCROLL:
			/*
			 * Forward N lines
			 * (default same as last 'd' or 'u' command).
			 */
			if (number > 0)
				wscroll = (int)number;
			cmd_exec();
			if (show_attn == OPT_ONPLUS)
				set_attnpos(bottompos);
			forward(wscroll, 0, 0);
			break;

		case A_B_SCROLL:
			/*
			 * Forward N lines
			 * (default same as last 'd' or 'u' command).
			 */
			if (number > 0)
				wscroll = (int)number;
			cmd_exec();
			backward(wscroll, 0, 0);
			break;

		case A_FREPAINT:
			/*
			 * Flush buffers, then repaint screen.
			 * Don't flush the buffers on a pipe!
			 */
			clear_buffers();
			/* FALLTHRU */
		case A_REPAINT:
			/*
			 * Repaint screen.
			 */
			cmd_exec();
			repaint();
			break;

		case A_GOLINE:
			/*
			 * Go to line N, default beginning of file.
			 */
			if (number <= 0)
				number = 1;
			cmd_exec();
			jump_back(number);
			break;

		case A_PERCENT:
			/*
			 * Go to a specified percentage into the file.
			 */
			if (number < 0) {
				number = 0;
				fraction = 0;
			}
			if (number > 100) {
				number = 100;
				fraction = 0;
			}
			cmd_exec();
			jump_percent((int)number, fraction);
			break;

		case A_GOEND:
			/*
			 * Go to line N, default end of file.
			 */
			cmd_exec();
			if (number <= 0)
				jump_forw();
			else
				jump_back(number);
			break;

		case A_GOPOS:
			/*
			 * Go to a specified byte position in the file.
			 */
			cmd_exec();
			if (number < 0)
				number = 0;
			jump_line_loc((off_t) number, jump_sline);
			break;

		case A_STAT:
			/*
			 * Print file name, etc.
			 */
			if (ch_getflags() & CH_HELPFILE)
				break;
			cmd_exec();
			parg.p_string = eq_message();
			error("%s", &parg);
			break;

		case A_VERSION:
			/*
			 * Print version number, without the "@(#)".
			 */
			cmd_exec();
			dispversion();
			break;

		case A_QUIT:
			/*
			 * Exit.
			 */
			if (curr_ifile != NULL_IFILE &&
			    ch_getflags() & CH_HELPFILE) {
				/*
				 * Quit while viewing the help file
				 * just means return to viewing the
				 * previous file.
				 */
				hshift = save_hshift;
				if (edit_prev(1) == 0)
					break;
			}
			if (extra != NULL)
				quit(*extra);
			quit(QUIT_OK);
			break;

/*
 * Define abbreviation for a commonly used sequence below.
 */
#define	DO_SEARCH() \
			if (number <= 0) number = 1;	\
			mca_search();			\
			cmd_exec();			\
			multi_search(NULL, (int)number);


		case A_F_SEARCH:
			/*
			 * Search forward for a pattern.
			 * Get the first char of the pattern.
			 */
			search_type = SRCH_FORW;
			if (number <= 0)
				number = 1;
			mca_search();
			c = getcc();
			goto again;

		case A_B_SEARCH:
			/*
			 * Search backward for a pattern.
			 * Get the first char of the pattern.
			 */
			search_type = SRCH_BACK;
			if (number <= 0)
				number = 1;
			mca_search();
			c = getcc();
			goto again;

		case A_FILTER:
			search_type = SRCH_FORW | SRCH_FILTER;
			mca_search();
			c = getcc();
			goto again;

		case A_AGAIN_SEARCH:
			/*
			 * Repeat previous search.
			 */
			DO_SEARCH();
			break;

		case A_T_AGAIN_SEARCH:
			/*
			 * Repeat previous search, multiple files.
			 */
			search_type |= SRCH_PAST_EOF;
			DO_SEARCH();
			break;

		case A_REVERSE_SEARCH:
			/*
			 * Repeat previous search, in reverse direction.
			 */
			save_search_type = search_type;
			search_type = SRCH_REVERSE(search_type);
			DO_SEARCH();
			search_type = save_search_type;
			break;

		case A_T_REVERSE_SEARCH:
			/*
			 * Repeat previous search,
			 * multiple files in reverse direction.
			 */
			save_search_type = search_type;
			search_type = SRCH_REVERSE(search_type);
			search_type |= SRCH_PAST_EOF;
			DO_SEARCH();
			search_type = save_search_type;
			break;

		case A_UNDO_SEARCH:
			undo_search();
			break;

		case A_HELP:
			/*
			 * Help.
			 */
			if (ch_getflags() & CH_HELPFILE)
				break;
			if (ungot != NULL || unget_end) {
				error(less_is_more
				    ? "Invalid option -p h"
				    : "Invalid option ++h",
				    NULL_PARG);
				break;
			}
			cmd_exec();
			save_hshift = hshift;
			hshift = 0;
			(void) edit(FAKE_HELPFILE);
			break;

		case A_EXAMINE:
			/*
			 * Edit a new file.  Get the filename.
			 */
			if (secure) {
				error("Command not available", NULL_PARG);
				break;
			}
			start_mca(A_EXAMINE, "Examine: ", ml_examine, 0);
			c = getcc();
			goto again;

		case A_VISUAL:
			/*
			 * Invoke an editor on the input file.
			 */
			if (secure) {
				error("Command not available", NULL_PARG);
				break;
			}
			if (ch_getflags() & CH_HELPFILE)
				break;
			if (strcmp(get_filename(curr_ifile), "-") == 0) {
				error("Cannot edit standard input", NULL_PARG);
				break;
			}
			if (curr_altfilename != NULL) {
				error("WARNING: This file was viewed via "
				    "LESSOPEN", NULL_PARG);
			}
			start_mca(A_SHELL, "!", ml_shell, 0);
			/*
			 * Expand the editor prototype string
			 * and pass it to the system to execute.
			 * (Make sure the screen is displayed so the
			 * expansion of "+%lm" works.)
			 */
			make_display();
			cmd_exec();
			lsystem(pr_expand(editproto, 0), NULL);
			break;

		case A_NEXT_FILE:
			/*
			 * Examine next file.
			 */
			if (ntags()) {
				error("No next file", NULL_PARG);
				break;
			}
			if (number <= 0)
				number = 1;
			if (edit_next((int)number)) {
				if (get_quit_at_eof() && eof_displayed() &&
				    !(ch_getflags() & CH_HELPFILE))
					quit(QUIT_OK);
				parg.p_string = (number > 1) ? "(N-th) " : "";
				error("No %snext file", &parg);
			}
			break;

		case A_PREV_FILE:
			/*
			 * Examine previous file.
			 */
			if (ntags()) {
				error("No previous file", NULL_PARG);
				break;
			}
			if (number <= 0)
				number = 1;
			if (edit_prev((int)number)) {
				parg.p_string = (number > 1) ? "(N-th) " : "";
				error("No %sprevious file", &parg);
			}
			break;

		case A_NEXT_TAG:
			if (number <= 0)
				number = 1;
			tagfile = nexttag((int)number);
			if (tagfile == NULL) {
				error("No next tag", NULL_PARG);
				break;
			}
			if (edit(tagfile) == 0) {
				off_t pos = tagsearch();
				if (pos != -1)
					jump_loc(pos, jump_sline);
			}
			break;

		case A_PREV_TAG:
			if (number <= 0)
				number = 1;
			tagfile = prevtag((int)number);
			if (tagfile == NULL) {
				error("No previous tag", NULL_PARG);
				break;
			}
			if (edit(tagfile) == 0) {
				off_t pos = tagsearch();
				if (pos != -1)
					jump_loc(pos, jump_sline);
			}
			break;

		case A_INDEX_FILE:
			/*
			 * Examine a particular file.
			 */
			if (number <= 0)
				number = 1;
			if (edit_index((int)number))
				error("No such file", NULL_PARG);
			break;

		case A_REMOVE_FILE:
			if (ch_getflags() & CH_HELPFILE)
				break;
			old_ifile = curr_ifile;
			new_ifile = getoff_ifile(curr_ifile);
			if (new_ifile == NULL_IFILE) {
				ring_bell();
				break;
			}
			if (edit_ifile(new_ifile) != 0) {
				reedit_ifile(old_ifile);
				break;
			}
			del_ifile(old_ifile);
			break;

		case A_OPT_TOGGLE:
			optflag = OPT_TOGGLE;
			optgetname = FALSE;
			mca_opt_toggle();
			c = getcc();
			goto again;

		case A_DISP_OPTION:
			/*
			 * Report a flag setting.
			 */
			optflag = OPT_NO_TOGGLE;
			optgetname = FALSE;
			mca_opt_toggle();
			c = getcc();
			goto again;

		case A_FIRSTCMD:
			/*
			 * Set an initial command for new files.
			 */
			start_mca(A_FIRSTCMD, "+", NULL, 0);
			c = getcc();
			goto again;

		case A_SHELL:
			/*
			 * Shell escape.
			 */
			if (secure) {
				error("Command not available", NULL_PARG);
				break;
			}
			start_mca(A_SHELL, "!", ml_shell, 0);
			c = getcc();
			goto again;

		case A_SETMARK:
			/*
			 * Set a mark.
			 */
			if (ch_getflags() & CH_HELPFILE)
				break;
			start_mca(A_SETMARK, "mark: ", (void*)NULL, 0);
			c = getcc();
			if (c == erase_char || c == erase2_char ||
			    c == kill_char || c == '\n' || c == '\r')
				break;
			setmark(c);
			break;

		case A_GOMARK:
			/*
			 * Go to a mark.
			 */
			start_mca(A_GOMARK, "goto mark: ", (void*)NULL, 0);
			c = getcc();
			if (c == erase_char || c == erase2_char ||
			    c == kill_char || c == '\n' || c == '\r')
				break;
			cmd_exec();
			gomark(c);
			break;

		case A_PIPE:
			if (secure) {
				error("Command not available", NULL_PARG);
				break;
			}
			start_mca(A_PIPE, "|mark: ", (void*)NULL, 0);
			c = getcc();
			if (c == erase_char || c == erase2_char ||
			    c == kill_char)
				break;
			if (c == '\n' || c == '\r')
				c = '.';
			if (badmark(c))
				break;
			pipec = c;
			start_mca(A_PIPE, "!", ml_shell, 0);
			c = getcc();
			goto again;

		case A_B_BRACKET:
		case A_F_BRACKET:
			start_mca(action, "Brackets: ", (void*)NULL, 0);
			c = getcc();
			goto again;

		case A_LSHIFT:
			if (number > 0)
				shift_count = number;
			else
				number = (shift_count > 0) ?
				    shift_count : sc_width / 2;
			if (number > hshift)
				number = hshift;
			hshift -= number;
			screen_trashed = 1;
			break;

		case A_RSHIFT:
			if (number > 0)
				shift_count = number;
			else
				number = (shift_count > 0) ?
				    shift_count : sc_width / 2;
			hshift += number;
			screen_trashed = 1;
			break;

		case A_PREFIX:
			/*
			 * The command is incomplete (more chars are needed).
			 * Display the current char, so the user knows
			 * what's going on, and get another character.
			 */
			if (mca != A_PREFIX) {
				cmd_reset();
				start_mca(A_PREFIX, " ", (void*)NULL,
				    CF_QUIT_ON_ERASE);
				(void) cmd_char(c);
			}
			c = getcc();
			goto again;

		case A_NOACTION:
			break;

		default:
			ring_bell();
			break;
		}
	}
}
Ejemplo n.º 15
0
void getenc(char **fontname, char **encname, encoding ev, int width[256])
{  int i, len, SCMseen, Ccnt, wx, cc;
   FILE *afm;
   char *name, ns;
   
   for (i=0; i < 256; i++) { ev[i] = NULL; width[i] = -1000; }
   if (encfile) {
      enc = fopen(encfile, "r");
      if (enc == NULL) fatal("Can't open %s\n", encfile);
      if (nextsymbol() != '/') fatal("missing '/encoding' in %s\n", encfile);
      *encname = nextpsname();
      if (nextsymbol() != '[') fatal("missing '[' in %s\n", encfile);
      i = 0;
      while (i < 256 && (ns = nextsymbol()) == '/') {
         name = my_string(pline);
         if (strcmp(name, ".notdef") == 0) { 
            i++; remove_string();
            continue; 
         }
         addcc(name, i++);
      }
      if (i != 256) fatal("missing %d symbols in %s\n", 256-i, encfile);
      if (nextsymbol() != ']') fatal("missing ']' in %s\n", encfile);
      fclose(enc);
   }
   afm = fopen(afmfile, "r");
   if (afm == NULL) fatal("Can't open %s\n", afmfile);
   /*
    * Scan header of AFM file and take the FontName and EncodingScheme
    * (used for identification purposes in the PK postamble)
    * Stop after reading `StartCharMetrics'.
    */
   SCMseen = 0; Ccnt = 0;
   while (fgets(line, LINEBUF-1, afm)) {
      if (strncmp(line, "FontName", 8) == 0) { 
	 pline = value_after(line, "FontName"); 
	 len = strlen(pline);
	 if (*(pline+len-1) == '\n') {
	    *(pline+len-1) = '\0'; len--;
	 }
	 *fontname = malloc(len + 1);
	 if (*fontname == NULL) fatal("Out of memory\n");
         strcpy(*fontname, pline);
      }
      else if (encname == NULL && strncmp(line, "EncodingScheme", 8) == 0) { 
	 pline = value_after(line, "EncodingScheme"); 
	 len = strlen(pline);
	 if (*(pline+len-1) == '\n') {
	    *(pline+len-1) = '\0'; len--;
	 }
	 *encname = malloc(len + 1);
	 if (*encname == NULL) fatal("Out of memory\n");
	 strcpy(*encname, pline);
      }
      else if (strncmp(line, "StartCharMetrics", 16) == 0) {
         SCMseen = 1; break;
      }
   }
   if (SCMseen == 0) fatal("%s: no metrics info\n", afmfile);
   while (fgets(line, LINEBUF-1, afm)) {
      if (strncmp(line, "EndCharMetrics", 14) == 0) break;
      if (strncmp(line, "C ", 2) != 0) 
         fatal("%s: unexpected line\n", afmfile);

      /* Gracefully terminate when the AFM file is not valid.  Every line */
      /* in the AFM file should specify a "C"haracter, a "WX"idth, and    */
      /* a "N"ame. (ndw)
      */
      pline = value_after(line, "C"); 
      if (pline == NULL)
         fatal("\nBad char metric in %s (no char):\n\t %s\n", afmfile, line);
      cc = decimal(pline);
      pline = value_after(pline, "WX"); 
      if (pline == NULL)
         fatal("\nBad char metric in %s (no width):\n\t %s\n", afmfile, line);
      wx = decimal(pline);
      pline = value_after(pline, "N"); 
      if (pline == NULL)
         fatal("\nBad char metric in %s (no name):\n\t %s\n", afmfile, line);
      name = my_string(pline);
      
      if (encfile) {
         if ((i = getcc(name)) == -1) {
            remove_string();
            continue;
	 }
         do { /* allow more occurences per name */
            ev[i] = name; width[i] = wx;
            i = getcc(name);
         }
         while (i >= 0);
      }
      else if (cc >= 0 && cc <= 255) { /* ndw: 10/13/92 */
	 ev[cc] = name; width[cc] = wx;
      }
      else if (cc > 255)
	 msg("Char code %d ignored (out of range).\n", cc);
      Ccnt++;
   }
   if (Ccnt == 0) fatal("%s: no characters selected\n", afmfile);   
}