Exemple #1
0
static void swstmt(int loop, int lab, int lev) {
	Tree e;
	struct swtch sw;
	Code head, tail;

	t = gettok();
	expect('(');
	definept(NULL);
	e = expr(')');
	if (!isint(e->type)) {
		error("illegal type `%t' in switch expression\n",
			e->type);
		e = retype(e, inttype);
	}
	e = cast(e, promote(e->type));
	if (generic(e->op) == INDIR && isaddrop(e->kids[0]->op)
	&& e->kids[0]->u.sym->type == e->type
	&& !isvolatile(e->kids[0]->u.sym->type)) {
		sw.sym = e->kids[0]->u.sym;
		walk(NULL, 0, 0);
	} else {
		sw.sym = genident(REGISTER, e->type, level);
		addlocal(sw.sym);
		walk(asgn(sw.sym, e), 0, 0);
	}
	head = code(Switch);
	sw.lab = lab;
	sw.deflab = NULL;
	sw.ncases = 0;
	sw.size = SWSIZE;
	sw.values = newarray(SWSIZE, sizeof *sw.values, FUNC);
	sw.labels = newarray(SWSIZE, sizeof *sw.labels, FUNC);
	refinc /= 10.0;
	statement(loop, &sw, lev);
	if (sw.deflab == NULL) {
		sw.deflab = findlabel(lab);
		definelab(lab);
		if (sw.ncases == 0)
			warning("switch statement with no cases\n");
	}
	if (findlabel(lab + 1)->ref)
		definelab(lab + 1);
	tail = codelist;
	codelist = head->prev;
	codelist->next = head->prev = NULL;
	if (sw.ncases > 0)
		swgen(&sw);
	branch(lab);
	head->next->prev = codelist;
	codelist->next = head->next;
	codelist = tail;
}
Exemple #2
0
void branch(int lab) {
	Code cp;
	Symbol p = findlabel(lab);

	assert(lab);
	walk(NULL, 0, 0);
	code(Label)->u.forest = jump(lab);
	for (cp = codelist->prev; cp->kind < Label; )
		cp = cp->prev;
	while (   cp->kind == Label
	       && cp->u.forest->op == LABEL+V
	       && !equal(cp->u.forest->syms[0], p)) {
		equatelab(cp->u.forest->syms[0], p);
		assert(cp->next);
		assert(cp->prev);
		cp->prev->next = cp->next;
		cp->next->prev = cp->prev;
		cp = cp->prev;
		while (cp->kind < Label)
			cp = cp->prev;
	}
	if (cp->kind == Jump || cp->kind == Switch) {
		p->ref--;
		codelist->prev->next = NULL;
		codelist = codelist->prev;
	} else {
		codelist->kind = Jump;
		if (cp->kind == Label
		&&  cp->u.forest->op == LABEL+V
		&&  equal(cp->u.forest->syms[0], p))
			warning("source code specifies an infinite loop");
	}
}
Exemple #3
0
Node jump(int lab) {
	Symbol p = findlabel(lab);

	p->ref++;
	return newnode(JUMP+V, newnode(ADDRG+ttob(voidptype), NULL, NULL, p),
		NULL, NULL);
}
Exemple #4
0
static void caselabel(Swtch swp, long val, int lab) {
	int k;

	if (swp->ncases >= swp->size)
		{
		long   *vals = swp->values;
		Symbol *labs = swp->labels;
		swp->size *= 2;
		swp->values = newarray(swp->size, sizeof *swp->values, FUNC);
		swp->labels = newarray(swp->size, sizeof *swp->labels, FUNC);
		for (k = 0; k < swp->ncases; k++) {
			swp->values[k] = vals[k];
			swp->labels[k] = labs[k];
		}
		}
	k = swp->ncases;
	for ( ; k > 0 && swp->values[k-1] >= val; k--) {
		swp->values[k] = swp->values[k-1];
		swp->labels[k] = swp->labels[k-1];
	}
	if (k < swp->ncases && swp->values[k] == val)
		error("duplicate case label `%d'\n", val);
	swp->values[k] = val;
	swp->labels[k] = findlabel(lab);
	++swp->ncases;
	if (Aflag >= 2 && swp->ncases == 258)
		warning("more than 257 cases in a switch\n");
}
Exemple #5
0
void Function::setconnections(LabelGenerator* l)
{   
	UUID id = l->getid();
    blocks.push_back(new CInstructionsContainer(id));
    blocks.back()->push_back( new FakeExitBlock );
    blocks.back()->push_back( new Unc_jump("Fake Exit Block", -3) );

	list<CInstructionsContainer*>::iterator i = blocks.begin();

	while ( i != blocks.end() )
	{
		if ( (*i)->onlylabel() )
		{
			list<CInstructionsContainer*>::iterator j = i;
			++i;
			(*i)->push_front( (*j)->front() );
			blocks.remove( (*j) );
		}
		else
			++i;
	}

	i = blocks.begin();

    while (  i != blocks.end())
    {
		if ( !(*i)->empty() ) {
        int lab = (*i)->back()->geti();
        if ( lab != -1 && (!(*i)->back()->islabel() ))
        {
            CInstructionsContainer* succ;
			succ = findlabel( lab );
			if (succ != NULL )
			{
				(*i)->succpush_back( succ );
				succ->predpush_back( *i );
			}
        }
        if ( !(*i)->back()->isuncjmp() && !(*i)->back()->isexit() && !(*i)->front()->isexit())
        {
			list<CInstructionsContainer*>::iterator j = i;
            ++i;
			if ( !(*i)->back()->isexit() )
			{
				(*i)->predpush_back( (*j) );
				(*j)->succpush_back( *i );
			}
        }else
			++i;
		} else
			++i;
	}

}
Exemple #6
0
static void forstmt(int lab, Swtch swp, int lev) {
	int once = 0;
	Tree e1 = NULL, e2 = NULL, e3 = NULL;
	Coordinate pt2, pt3;
	
	t = gettok();
	expect('(');
	definept(NULL);
	if (kind[t] == ID)
		e1 = texpr(expr0, ';', FUNC);
	else
		expect(';');
	walk(e1, 0, 0);
	pt2 = src;
	refinc *= 10.0;
	if (kind[t] == ID)
		e2 = texpr(conditional, ';', FUNC);
	else
		expect(';');
	pt3 = src;
	if (kind[t] == ID)
		e3 = texpr(expr0, ')', FUNC);
	else {
		static char stop[] = { IF, ID, '}', 0 };
		test(')', stop);
	}
	if (e2) {
		once = foldcond(e1, e2);
		if (!once)
			branch(lab + 3);
	}
	definelab(lab);
	statement(lab, swp, lev);
	definelab(lab + 1);
	definept(&pt3);
	if (e3)
		walk(e3, 0, 0);
	if (e2) {
		if (!once)
			definelab(lab + 3);
		definept(&pt2);
		walk(e2, lab, 0);
	} else {
		definept(&pt2);
		branch(lab);
	}
	if (findlabel(lab + 2)->ref)
		definelab(lab + 2);
}
Exemple #7
0
/*
** export pending gotos to outer level, to check them against
** outer labels; if the block being exited has upvalues, and
** the goto exits the scope of any variable (which can be the
** upvalue), close those variables being exited.
*/
static void movegotosout (FuncState *fs, BlockCnt *bl) {
  int i = bl->firstgoto;
  Labellist *gl = &fs->ls->dyd->gt;
  /* correct pending gotos to current block and try to close it
     with visible labels */
  while (i < gl->n) {
    Labeldesc *gt = &gl->arr[i];
    if (gt->nactvar > bl->nactvar) {
      if (bl->upval)
        luaK_patchclose(fs, gt->pc, bl->nactvar);
      gt->nactvar = bl->nactvar;
    }
    if (!findlabel(fs->ls, i))
      i++;  /* move to next one */
  }
}
Exemple #8
0
static void ifstmt(int lab, int loop, Swtch swp, int lev) {
	t = gettok();
	expect('(');
	definept(NULL);
	walk(conditional(')'), 0, lab);
	refinc /= 2.0;
	statement(loop, swp, lev);
	if (t == ELSE) {
		branch(lab + 1);
		t = gettok();
		definelab(lab);
		statement(loop, swp, lev);
		if (findlabel(lab + 1)->ref)
			definelab(lab + 1);
	} else
		definelab(lab);
}
Exemple #9
0
void	changepc(char *line, int *pc)
{
  int	i;
  int	j;

  i = 0;
  j = 0;
  if (findlabel(line) == 1)
    {
      while (line[i] != ' ' && line[i] != '\0')
        i++;
      if (line[i] == 0)
	return ;
      i++;
    }
  while (my_instructcmp(&line[i], op_tab[j].mnemonique, ' ') == 0 && j < 16)
    j++;
  if (my_instructcmp(&line[i], op_tab[j].mnemonique, ' ') == 0)
    return ;
  adress(j, &line[i], pc);
}
Exemple #10
0
void definelab(int lab) {
	Code cp;
	Symbol p = findlabel(lab);

	assert(lab);
	walk(NULL, 0, 0);
	code(Label)->u.forest = newnode(LABEL+V, NULL, NULL, p);
	for (cp = codelist->prev; cp->kind <= Label; )
		cp = cp->prev;
	while (   cp->kind == Jump
	       && cp->u.forest->kids[0]
	       && specific(cp->u.forest->kids[0]->op) == ADDRG+P
	       && cp->u.forest->kids[0]->syms[0] == p) {
		assert(cp->u.forest->kids[0]->syms[0]->u.l.label == lab);
		p->ref--;
		assert(cp->next);
		assert(cp->prev);
		cp->prev->next = cp->next;
		cp->next->prev = cp->prev;
		cp = cp->prev;
		while (cp->kind <= Label)
			cp = cp->prev;
	}
}
Exemple #11
0
static int number(char *s, char *e)
{
   object		*l;

   if (*s == '*') return 0;
   if (*s == '(') return number(s+1, e-1);

   if (s < e) l = findlabel(s, e);
   else                  return 1;

   if (!l)
   {
      if (label_highest_byte == 0) return 1;
      return 0;
   }

   if (l->l.r.l.rel) return 0;
   if (l->l.valued == 0) return 0;
   if (l->l.r.l.xref < 0) return 0;
   if (l->l.valued == EQUF) return 0;
   if (l->l.valued & 128) return 0;

   return 1;
}
Exemple #12
0
void statement(int loop, Swtch swp, int lev) {
	float ref = refinc;

	if (Aflag >= 2 && lev == 15)
		warning("more than 15 levels of nested statements\n");
	switch (t) {
	case IF:       ifstmt(genlabel(2), loop, swp, lev + 1);
 break;
	case WHILE:    whilestmt(genlabel(3), swp, lev + 1); break;
	case DO:       dostmt(genlabel(3), swp, lev + 1); expect(';');
					break;

	case FOR:      forstmt(genlabel(4), swp, lev + 1);
 break;
	case BREAK:    walk(NULL, 0, 0);
		       definept(NULL);
		       if (swp && swp->lab > loop)
		       	branch(swp->lab + 1);
		       else if (loop)
		       	branch(loop + 2);
		       else
		       	error("illegal break statement\n");
		       t = gettok(); expect(';');
					   break;

	case CONTINUE: walk(NULL, 0, 0);
		       definept(NULL);
		       if (loop)
		       	branch(loop + 1);
		       else
		       	error("illegal continue statement\n");
		       t = gettok(); expect(';');
					      break;

	case SWITCH:   swstmt(loop, genlabel(2), lev + 1);
 break;
	case CASE:     {
		       	int lab = genlabel(1);
		       	if (swp == NULL)
		       		error("illegal case label\n");
		       	definelab(lab);
		       	while (t == CASE) {
		       		static char stop[] = { IF, ID, 0 };
		       		Tree p;
		       		t = gettok();
		       		p = constexpr(0);
		       		if (generic(p->op) == CNST && isint(p->type)) {
		       			if (swp) {
		       				needconst++;
		       				p = cast(p, swp->sym->type);
		       				if (p->type->op == UNSIGNED)
		       					p->u.v.i = extend(p->u.v.u, p->type);
		       				needconst--;
		       				caselabel(swp, p->u.v.i, lab);
		       			}
		       		} else
		       			error("case label must be a constant integer expression\n");

		       		test(':', stop);
		       	}
		       	statement(loop, swp, lev);
		       } break;
	case DEFAULT:  if (swp == NULL)
		       	error("illegal default label\n");
		       else if (swp->deflab)
		       	error("extra default label\n");
		       else {
		       	swp->deflab = findlabel(swp->lab);
		       	definelab(swp->deflab->u.l.label);
		       }
		       t = gettok();
		       expect(':');
		       statement(loop, swp, lev); break;
	case RETURN:   {
		       	Type rty = freturn(cfunc->type);
		       	t = gettok();
		       	definept(NULL);
		       	if (t != ';')
		       		if (rty == voidtype) {
		       			error("extraneous return value\n");
		       			expr(0);
		       			retcode(NULL);
		       		} else
		       			retcode(expr(0));
		       	else {
		       		if (rty != voidtype)
		       			warning("missing return value\n");
		       		retcode(NULL);
		       	}
		       	branch(cfunc->u.f.label);
		       } expect(';');
					    break;

	case '{':      compound(loop, swp, lev + 1); break;
	case ';':      definept(NULL); t = gettok(); break;
	case GOTO:     walk(NULL, 0, 0);
		       definept(NULL);
		       t = gettok();
		       if (t == ID) {
		       	Symbol p = lookup(token, stmtlabs);
		       	if (p == NULL) {
				p = install(token, &stmtlabs, 0, FUNC);
				p->scope = LABELS;
				p->u.l.label = genlabel(1);
				p->src = src;
			}
		       	use(p, src);
		       	branch(p->u.l.label);
		       	t = gettok();
		       } else
		       	error("missing label in goto\n"); expect(';');
					  break;

	case ID:       if (getchr() == ':') {
		       	stmtlabel();
		       	statement(loop, swp, lev);
		       	break;
		       }
	default:       definept(NULL);
		       if (kind[t] != ID) {
		       	error("unrecognized statement\n");
		       	t = gettok();
		       } else {
		       	Tree e = expr0(0);
		       	listnodes(e, 0, 0);
		       	if (nodecount == 0 || nodecount > 200)
		       		walk(NULL, 0, 0);
		       	else if (glevel) walk(NULL, 0, 0);
		       	deallocate(STMT);
		       } expect(';');
						break;

	}
	if (kind[t] != IF && kind[t] != ID
	&& t != '}' && t != EOI) {
		static char stop[] = { IF, ID, '}', 0 };
		error("illegal statement termination\n");
		skipto(0, stop);
	}
	refinc = ref;
}
Exemple #13
0
static void
calcfirstset(grammar *g, dfa *d)
{
	int i, j;
	state *s;
	arc *a;
	int nsyms;
	int *sym;
	int nbits;
	static bitset dummy;
	bitset result;
	int type;
	dfa *d1;
	label *l0;
	
	if (Py_DebugFlag)
		printf("Calculate FIRST set for '%s'\n", d->d_name);
	
	if (dummy == NULL)
		dummy = newbitset(1);
	if (d->d_first == dummy) {
		fprintf(stderr, "Left-recursion for '%s'\n", d->d_name);
		return;
	}
	if (d->d_first != NULL) {
		fprintf(stderr, "Re-calculating FIRST set for '%s' ???\n",
			d->d_name);
	}
	d->d_first = dummy;
	
	l0 = g->g_ll.ll_label;
	nbits = g->g_ll.ll_nlabels;
	result = newbitset(nbits);
	
	sym = (int *)PyObject_MALLOC(sizeof(int));
	if (sym == NULL)
		Py_FatalError("no mem for new sym in calcfirstset");
	nsyms = 1;
	sym[0] = findlabel(&g->g_ll, d->d_type, (char *)NULL);
	
	s = &d->d_state[d->d_initial];
	for (i = 0; i < s->s_narcs; i++) {
		a = &s->s_arc[i];
		for (j = 0; j < nsyms; j++) {
			if (sym[j] == a->a_lbl)
				break;
		}
		if (j >= nsyms) { /* New label */
			sym = (int *)PyObject_REALLOC(sym, 
                                                sizeof(int) * (nsyms + 1));
			if (sym == NULL)
				Py_FatalError(
				    "no mem to resize sym in calcfirstset");
			sym[nsyms++] = a->a_lbl;
			type = l0[a->a_lbl].lb_type;
			if (ISNONTERMINAL(type)) {
				d1 = PyGrammar_FindDFA(g, type);
				if (d1->d_first == dummy) {
					fprintf(stderr,
						"Left-recursion below '%s'\n",
						d->d_name);
				}
				else {
					if (d1->d_first == NULL)
						calcfirstset(g, d1);
					mergebitset(result,
						    d1->d_first, nbits);
				}
			}
			else if (ISTERMINAL(type)) {
				addbit(result, a->a_lbl);
			}
		}
	}
	d->d_first = result;
	if (Py_DebugFlag) {
		printf("FIRST set for '%s': {", d->d_name);
		for (i = 0; i < nbits; i++) {
			if (testbit(result, i))
				printf(" %s", PyGrammar_LabelRepr(&l0[i]));
		}
		printf(" }\n");
	}

	PyObject_FREE(sym);
}
Exemple #14
0
/* Execute a block.  There can be a number of return values from this routine.
 *  NORMAL indicates a normal termination
 *  BROKEN indicates a break -- if the caller is a breakable loop,
 *      terminate it, otherwise pass the break upwards
 *  CONTINUED indicates a continue -- if the caller is a continuable loop,
 *      continue, else pass the continue upwards
 *  Any other return code is considered a pointer to a string which is
 *      a label somewhere -- if this label is present in the block,
 *      goto it, otherwise pass it up. Note that this prevents jumping
 *      into a loop, which is good.
 *
 * Note that here is where we expand variables, ``, and globs for
 * controls.
 *
 * The 'num' argument is used by break n and continue n.  */
static char *
doblock(struct control *bl, int *num)
{
    struct control *ch, *cn = NULL;
    wordlist *wl, *wltmp;
    char *i, *wlword;
    int nn;

    nn = *num + 1; /*CDHW this is a guess... CDHW*/

    switch (bl->co_type) {
    case CO_WHILE:
        if (!bl->co_children) {
            fprintf(cp_err, "Warning: Executing empty 'while' block.\n");
            fprintf(cp_err, "         (Use a label statement as a no-op to suppress this warning.)\n");
        }
        while (bl->co_cond && cp_istrue(bl->co_cond)) {
            if (!bl->co_children) cp_periodic();  /*CDHW*/
            for (ch = bl->co_children; ch; ch = cn) {
                cn = ch->co_next;
                i = doblock(ch, &nn);
                switch (*i) {

                case NORMAL:
                    break;

                case BROKEN:    /* Break. */
                    if (nn < 2) {
                        return (NORMAL_STR);
                    } else {
                        *num = nn - 1;
                        return (BROKEN_STR);
                    }

                case CONTINUED: /* Continue. */
                    if (nn < 2) {
                        cn = NULL;
                        break;
                    } else {
                        *num = nn - 1;
                        return (CONTINUED_STR);
                    }

                default:
                    cn = findlabel(i, bl->co_children);
                    if (!cn)
                        return (i);
                }
            }
        }
        break;

    case CO_DOWHILE:
        do {
            for (ch = bl->co_children; ch; ch = cn) {
                cn = ch->co_next;
                i = doblock(ch, &nn);
                switch (*i) {

                case NORMAL:
                    break;

                case BROKEN:    /* Break. */
                    if (nn < 2) {
                        return (NORMAL_STR);
                    } else {
                        *num = nn - 1;
                        return (BROKEN_STR);
                    }

                case CONTINUED: /* Continue. */
                    if (nn < 2) {
                        cn = NULL;
                        break;
                    } else {
                        *num = nn - 1;
                        return (CONTINUED_STR);
                    }

                default:
                    cn = findlabel(i, bl->co_children);
                    if (!cn)
                        return (i);
                }
            }
        } while (bl->co_cond && cp_istrue(bl->co_cond));
        break;

    case CO_REPEAT:
        if (!bl->co_children) {
            fprintf(cp_err, "Warning: Executing empty 'repeat' block.\n");
            fprintf(cp_err, "         (Use a label statement as a no-op to suppress this warning.)\n");
        }
        if (!bl->co_timestodo) bl->co_timestodo = bl->co_numtimes;
        /*bl->co_numtimes: total repeat count
          bl->co_numtimes = -1: repeat forever
          bl->co_timestodo: remaining repeats*/
        while ((bl->co_timestodo > 0) ||
               (bl->co_timestodo == -1)) {
            if (!bl->co_children) cp_periodic();  /*CDHW*/
            if (bl->co_timestodo != -1) bl->co_timestodo--;
            /* loop through all stements inside rpeat ... end */
            for (ch = bl->co_children; ch; ch = cn) {
                cn = ch->co_next;
                i = doblock(ch, &nn);
                switch (*i) {

                case NORMAL:
                    break;

                case BROKEN:    /* Break. */
                    /* before leaving repeat loop set remaining timestodo to 0 */
                    bl->co_timestodo = 0;
                    if (nn < 2) {
                        return (NORMAL_STR);
                    } else {
                        *num = nn - 1;
                        return (BROKEN_STR);
                    }

                case CONTINUED: /* Continue. */
                    if (nn < 2) {
                        cn = NULL;
                        break;
                    } else {
                        /* before leaving repeat loop set remaining timestodo to 0 */
                        bl->co_timestodo = 0;
                        *num = nn - 1;
                        return (CONTINUED_STR);
                    }

                default:
                    cn = findlabel(i, bl->co_children);

                    if (!cn) {
                        /* no label found inside repeat loop:
                           before leaving loop set remaining timestodo to 0 */
                        bl->co_timestodo = 0;
                        return (i);
                    }
                }
            }
        }
        break;

    case CO_IF:
        if (bl->co_cond && cp_istrue(bl->co_cond)) {
            for (ch = bl->co_children; ch; ch = cn) {
                cn = ch->co_next;
                i = doblock(ch, &nn);
                if (*i > 2) {
                    cn = findlabel(i,
                                   bl->co_children);
                    if (!cn)
                        return (i);
                    else
                        tfree(i);
                } else if (*i != NORMAL) {
                    *num = nn;
                    return (i);
                }
            }
        } else {
            for (ch = bl->co_elseblock; ch; ch = cn) {
                cn = ch->co_next;
                i = doblock(ch, &nn);
                if (*i > 2) {
                    cn = findlabel(i, bl->co_elseblock);
                    if (!cn)
                        return (i);
                } else if (*i != NORMAL) {
                    *num = nn;
                    return (i);
                }
            }
        }
        break;

    case CO_FOREACH:
        wltmp = cp_variablesubst(cp_bquote(cp_doglob(wl_copy(bl->co_text))));
        for (wl = wltmp; wl; wl = wl->wl_next) {
            cp_vset(bl->co_foreachvar, CP_STRING, wl->wl_word);
            for (ch = bl->co_children; ch; ch = cn) {
                cn = ch->co_next;
                i = doblock(ch, &nn);
                switch (*i) {

                case NORMAL:
                    break;

                case BROKEN:    /* Break. */
                    if (nn < 2) {
                        wl_free(wltmp);
                        return (NORMAL_STR);
                    } else {
                        *num = nn - 1;
                        wl_free(wltmp);
                        return (BROKEN_STR);
                    }

                case CONTINUED: /* Continue. */
                    if (nn < 2) {
                        cn = NULL;
                        break;
                    } else {
                        *num = nn - 1;
                        wl_free(wltmp);
                        return (CONTINUED_STR);
                    }

                default:
                    cn = findlabel(i, bl->co_children);
                    if (!cn) {
                        wl_free(wltmp);
                        return (i);
                    }
                }
            }
        }
        wl_free(wltmp);
        break;

    case CO_BREAK:
        if (bl->co_numtimes > 0) {
            *num = bl->co_numtimes;
            return (BROKEN_STR);
        } else {
            fprintf(cp_err, "Warning: break %d a no-op\n",
                    bl->co_numtimes);
            return (NORMAL_STR);
        }

    case CO_CONTINUE:
        if (bl->co_numtimes > 0) {
            *num = bl->co_numtimes;
            return (CONTINUED_STR);
        } else {
            fprintf(cp_err, "Warning: continue %d a no-op\n",
                    bl->co_numtimes);
            return (NORMAL_STR);
        }

    case CO_GOTO:
        wl = cp_variablesubst(cp_bquote(cp_doglob(wl_copy(bl->co_text))));
        wlword = wl->wl_word;
        wl->wl_word = NULL;
        wl_free(wl);
        return (wlword);

    case CO_LABEL:
        /* Do nothing. */
        cp_periodic();  /*CDHW needed to avoid lock-ups when loop contains only a label CDHW*/
        break;

    case CO_STATEMENT:
        docommand(wl_copy(bl->co_text));
        break;

    case CO_UNFILLED:
        /* There was probably an error here... */
        fprintf(cp_err, "Warning: ignoring previous error\n");
        break;

    default:
        fprintf(cp_err,
                "doblock: Internal Error: bad block type %d\n",
                bl->co_type);
        return (NORMAL_STR);
    }
    return (NORMAL_STR);
}