⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdecl.c

📁 微软的基于HMM的人脸识别原代码, 非常经典的说
💻 C
📖 第 1 页 / 共 4 页
字号:
    {
	struct_t * S;
	int n;
	S = EiC_getInf(type);
	n = S->n;
	S->n = 1;  /* force initialisation of first member only */	
	initstruct(type,addr,lev+1);
	S->n = n;
    }
	break;
      default:
	assign_var(type, *addr,0); break;
    }
}

static void initstruct(type_expr * type, void **addr, int lev)
{ 
    if(EiC_lexan() == '{' ) {
	do_struct(type,addr,lev);
	if(lev > 1 && EiC_lexan() != ',')
		retractlexan();
	EiC_match('}', " }");
    } else { 
	retractlexan();
	if(lev > 0) 
	    do_struct(type,addr,lev);
	else /* else intializer must be an expression of the same type */
	    assign_var(type,*addr,1);
    }
}

static void do_struct(type_expr *type, void **addr,int lev)
{
    struct_t *S;
    int i;
    S = EiC_getInf(type);
    for(i=0;i<S->n;i++) 
	if(EiC_lexan() != '}') {
	    retractlexan();
	    *addr = (char*)*addr + S->offset[i];
	    initglobal(S->type[i],addr,lev+1);
	    *addr = (char*)*addr - S->offset[i];
	    if(EiC_lexan() != ',' && i != S->n-1)
		retractlexan();
	} else {
	    break;
	}

    retractlexan();

}

static int dostrlit(void ** addr,int ln, int sln, char * str)
{    /*
      * parse eg. char a[] = "hello world";
      * or  char a[5] = "hello world";
      */    
    xmark(str,eicgstring); /* mark for garbage collector */
    if(ln) {
	if(sln >= ln)
	    EiC_warningerror("Array of chars is too long");
    } else {
	ln = sln+1; /* allow for null at end */
	*addr = xrealloc(*addr,ln);
    }
   if(sln < ln)
	memcpy(*addr,str,sln+1);
   else
       memcpy(*addr,str,ln);
	
    return ln;
}

static int initarray(type_expr * type, void ** addr, int size, int lev)
{
    static int INCREMENT;
    
    if(EiC_gettype(type) == t_array) {
	int t,tok,s;
	if((tok =EiC_lexan()) == '{') {
	    t = EiC_get_sizeof(type);
	    if(lev == 0) 
		INCREMENT = t == 0 ? EiC_get_sizeof(nextType(type)): 0;
	    s = do_array(nextType(type),addr,t,lev,INCREMENT);
	    if(t == 0) {
		int sz = EiC_get_sizeof(nextType(type));
		if(sz)
		    t = s/sz;
		else
		    EiC_error("Ilegal array domain in initialisation");
		setNumElems(type,t);
	    }
	    EiC_match('}'," }");
	} else if(tok == STR) { /* handle string literals */
	    if(EiC_gettype(nextType(type)) == t_char) {
		size_t sln;
		t = EiC_get_sizeof(type);
		sln = (char*)token->Val.p.ep - (char*)token->Val.p.p - 1;
		s = dostrlit(addr,t,sln,token->Val.p.p);
		if(lev == 0 && t == 0)
		    setNumElems(type,s);
	    }else
		EiC_error("Illegal initialisation");
	} else{
	    retractlexan();
	    if(lev > 0) /* lev indicates a recusive call */
		size = do_array(nextType(type),addr,size,lev,INCREMENT);
	    else 
		EiC_error("missing { in initialisation of an array");
	}
    } else
	initglobal(type,addr,lev+1);
    return size;
}

static int do_array(type_expr *type, void ** addr, int size, int lev, int inc)
{

    int n = 0;
    while(EiC_lexan() != '}') {
	retractlexan();
	if(n >= size) {
	    if(inc) {
		size += inc;
		*addr = xrealloc(*addr, size);
		memset((char*)*addr + size - inc, 0, inc);
	    } else {
		if(size)
		    EiC_error("Too many initialisers");
		else
		    EiC_error("Illegal domain for initialisation");
	    }
	}
	*addr = (char*)*addr + n;
	size = initarray(type,addr, size,lev+1);
	*addr = (char*)*addr - n;
	n += EiC_get_sizeof(type);
	if (EiC_lexan() != ',') 
	    break;
	    
    } 
    retractlexan();
    return size;
}

static void assign_var(type_expr *type, void *addr,int allow)
{
    int t;
    token_t e1,e2;
    void *EiC_getaddress(token_t *);
    

    EiC_inittoken(&e2);
    EiC_assign_expr(&e2);

#if 0
    if(IsTemp(e2.Type))
	EiC_clearTempories();
#endif
    
    t = EiC_gettype(type);

    if (isconst(e2.Type)) {
	e1.Type = type;
	EiC_castconst(&e2,&e1,0);
	switch(t) {
	  case t_char:  
	  case t_uchar:    *(char*)addr = e2.Val.ival; break;
	  case t_short:
	  case t_ushort:  *(short*)addr = e2.Val.ival; break;
	  case t_int:
	  case t_uint:     *(int *)addr = e2.Val.ival; break;
	  case t_long:
	  case t_ulong:    *(long*)addr = e2.Val.lval; break;
	case t_llong:      *(eic_llong*)addr = e2.Val.llval; break;
	  case t_float:   *(float*)addr = e2.Val.dval; break;
	  case t_double: *(double*)addr = e2.Val.dval; break;
	  case t_pointer: 
	    if(EiC_S_LEVEL == 1 && EiC_gettype(e2.Type) == t_pointer
	       && EiC_gettype(nextType(e2.Type)) == t_char
               && !e2.Sym) 
		/* got string */
		if(e2.Val.p.p)
		    EiC_SaveGlobalString(&e2.Val.p);
	    if(issafe(type))
	       *(ptr_t*)addr = e2.Val.p;
	    else
	       *(void**)addr = e2.Val.p.p;
	    break;
	    
	  default:
	    EiC_error("Unknown initialiserXXX");
	}
    } else if(allow) {
	val_t h;
	token_t e3;
	EiC_inittoken(&e3);
	e3.Type = type;
	EiC_output(&e2);
	EiC_castvar(&e2,&e3,0);	
	if (t == t_struct || t == t_union) 
	    structUnionCode(E1,&e2);
	h = E1->Val;
	E1->Val = E1->Sym->val;
	EiC_concode(&E1->Code,&e2.Code);
	EiC_do_stooutput(E1);
	E1->Val = h;
    } else {
	if(EiC_GI(&e2) != 0)   /* global or static addresses only are allowed */
	    EiC_error("Illegal initialization: illegal address operation");
	else {
	    /*e1.Type = type;*/
	    /*EiC_output(&e2);*/
	    /*EiC_castvar(&e2,&e1,1);*/
	    if(EiC_gettype(type) == t_pointer || 
	               (e2.Sym && EiC_gettype(e2.Sym->type) == t_ref)) {
		ptr_t p;
		p.sp = p.p = EiC_getaddress(&e2);
		p.ep = (char*)p.p + EiC_get_sizeof(e2.Type);
		if(!EiC_sametypes(e2.Type,type))
		    EiC_warningerror("Suspicious pointer conversion");
		if(issafe(type))
		    *(ptr_t*)addr = p;
		else
		    *(void**)addr = p.p;
		EiC_freecode(&e2.Code);
	    } else
		EiC_error("Expected constant expression as an"
		      " initialiser");
	}
    }
    EiC_freetoken(&e2);
}


static void decl(token_t * e1, int t)
{
    type_expr *P = NULL;
    switch (t) {
      case '*':
	P = pointer();
	dir_decl(e1, EiC_lexan());
	if(P)
	    e1->Type = EiC_catTypes(P,e1->Type);
	break;
      case ID:
      case '(':
	dir_decl(e1, t);
	break;
      default:
	EiC_error("Declarator error");
	retractlexan();
    }

}

static type_expr * pointer(void)
{
    type_expr *t = NULL;
    do {
	t = EiC_addtype(t_pointer,t);
	if(EiC_lexan() == constsym || token->Tok == volatilesym) {
	    if(token->Tok == constsym) {
		setConstp(t);
	    }
	    /*ignore volatilesym for now*/
	    EiC_lexan();
	}
	/* pointer qualifer */
	if(token->Tok == safesym) {
	  unsetPtr(t);

	  setSafe(t);
	  EiC_lexan();
	} else  if(token->Tok == unsafesym) {
	  unsetPtr(t);
	  setUnSafe(t);
	  EiC_lexan();
	}
    } while (token->Tok == '*');
    retractlexan();
    return t;
}

static void dir_decl(token_t * e1, int t)
{
    switch (t) {
      case '(':
	decl(e1, EiC_lexan());
	EiC_match(')', " )");
	f_dir_decl(e1);
	break;
	
      case ID:

	init_ident(e1, EiC_work_tab);
	f_dir_decl(e1);
	break;
	
      default:
	EiC_error("Direct declarator error");
	break;
    }
}

static void f_dir_decl(token_t * e1)
{
    while (1)
	switch (EiC_lexan()) {
	  case '[':
	    array_decl(e1);
	    break;
	  case '(':
	    ff_dir_decl(e1);
	    if(INPARMLIST)
		EiC_remlevel(EiC_S_LEVEL+1);
	    break;
	  default:
	    retractlexan();
	    return;
	}
}

static void ff_dir_decl(token_t * e1)
{

    int h;
    switch ((h=EiC_lexan())) {
      TYPEQUAL:
      STORECLASS:
      TYPESPEC:
	EiC_S_LEVEL++;
	RESET++;
	h = LSP;
	LSP = EiC_ENV->lsp;
	retractlexan();
	EiC_make_func(e1);
	/*
	 * Use INPARMLIST to inform other
	 * modules that the following declarations
	 * are function parameters.
	 */
	INPARMLIST++;
	PRAMHANDLE = e1->Type;

	parm_type_list(EiC_getInf(e1->Type));
	/*
	 * now pseudo reverse the parameter
	 * order.
	 */
	EiC_reset_env_pointers(e1, LSP);
	LSP = h;
	RESET--;

	INPARMLIST--;
	EiC_S_LEVEL--;
	
	break;
      case ')':
	/*
	 * This should really be made illegal, it allows
	 * for function declarations with empty
	 * paramater list, such as:
	 * int f(); Therefore, force an implied t_var argument.
	 */
    {
	type_expr * type;
	EiC_make_func(e1);
	type = EiC_addtype(t_var,NULL);
	EiC_add_func_parm(EiC_getInf(e1->Type), &type, NULL);
	EiC_freetype(type);
    }
	return;
      default:
	if(h == ID)
	    EiC_error("Unknown type '%s': possible "
		  "old C type declaration", token->Val.sym->id);
	else
	    EiC_error("Syntax error");
    }
    EiC_match(')', " )");
}


static void UpDateParmSym(type_expr *ty, symentry_t *sym)
{
    if(EiC_gettype(ty) == t_pointer && EiC_gettype(nextType(ty)) ==
       t_funcdec)
	if(EiC_gettype(sym->type) != t_pointer)
	    sym->type = EiC_addtype(t_pointer,sym->type);
}

static void parm_type_list(func_t * f)
{
    extern int Pclash;
    char * name = NULL;
    token_t e2;
    EiC_inittoken(&e2);
    parm_decl(&e2);
    /*
     * Must watch out for void  as a parameter.
     * The void paramater will have no sym entry.
     */
    if(e2.Val.sym) {
	new_var(&e2);
#if 1
	{
	    void EiC_adjustParam(type_expr **type);
	    EiC_adjustParam(&e2.Sym->type);
	}
#endif

	name = e2.Sym->id;
    } else  /* still must reverse type if needed */
	e2.Type = EiC_revtype(e2.Type);

    EiC_add_func_parm(f, &e2.Type,name);
    if(!e2.Val.sym)
	EiC_freetype(e2.Type);
    else
	UpDateParmSym(getFPty(f,getFNp(f)-1),e2.Val.sym);
    
    if(Pclash)
	Pclash = 0;

    if (EiC_lexan() == ',')
	f_parm_type_list(f);
    else
	retractlexan();
}

static void f_parm_type_list(func_t * f)
{
    if (EiC_lexan() == '.') {
	if (EiC_lexan() == '.')
	    if (EiC_lexan() == '.') {
		type_expr *type;
		type = EiC_addtype(t_var, NULL);
		EiC_add_func_parm(f, &type,NULL);
		EiC_freetype(type);
		return;
	    }
	retractlexan();
	EiC_error("Expected ...");
    } else {
	retractlexan();
	parm_type_list(f);
    }
}

static void fff_parm_decl(token_t *e1);
static void ff_parm_decl(token_t *e1);
static void f_parm_decl(token_t * e1);

static void parm_decl(token_t * e1)
{
    switch (EiC_lexan()) {
      TYPEQUAL:
      STORECLASS:
      TYPESPEC:
	decl_spec(e1);
	f_parm_decl(e1);
	break;
      default:
	if(token->Tok == ID)
	    EiC_error("Unknown type '%s'",token->Val.sym->id);
	else
	    EiC_error("Parameter declaration error");
    }
}


static void f_parm_decl(token_t * e1)
{
    if(EiC_lexan() == '*') {
	type_expr *P = NULL;
	P = pointer();
	ff_parm_decl(e1);
	if(P)
	    e1->Type = EiC_catTypes(P,e1->Type);	
    } else {
	retractlexan();
	ff_parm_decl(e1);
    }
}


static void ff_parm_decl(token_t *e1)
{
    switch(EiC_lexan()) {
      case ID: init_ident(e1, EiC_work_tab);
	f_dir_decl(e1);
	break;
      case '(': fff_parm_decl(e1);
	break;
      case '[': retractlexan();
	f_dir_decl(e1);
	break;
      default: /* null */
	if(token->Tok  != ',' && token->Tok != ')')
	    EiC_error("Parameter declaration error");
	else
	    retractlexan();
	return ;	
    }
}

static void fff_parm_decl(token_t *e1)
{
    switch(EiC_lexan()) {
      TYPEQUAL:
      STORECLASS:
      TYPESPEC:
	retractlexan();
	ff_dir_decl(e1);
	EiC_remlevel(EiC_S_LEVEL+1);
	break;
      default:
	retractlexan();
	f_parm_decl(e1);
	EiC_match(')', " ) "); 
	break;
    }
    f_dir_decl(e1);
}


static void enum_spec(token_t * e1)
{
    e1->Type = EiC_addtype(t_enum, NULL);
    f_enum_spec(e1);
}

static void f_enum_spec(token_t * e1)
{
    int h, t, nxtt;
    h = EiC_work_tab;
    EiC_work_tab = tag_tab;
    switch (EiC_lexan()) {
      case ID:			/* enumeration tag */
	t = EiC_gettype(token->Val.sym->type);
	nxtt = EiC_lexan();
	retractlexan();

	if (nxtt == '{' || t == ID) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -