示例#1
0
文件: Image.cpp 项目: ONLYOFFICE/core
    static void CorrectImage(const wchar_t* wsFileName, BYTE*& pBuffer, int& nBufferSize, unsigned int& unWidth, unsigned int& unHeight)
    {
        pBuffer = NULL;
        nBufferSize = 0;

        CImageFileFormatChecker oChecker(wsFileName);
        if (oChecker.eFileType != _CXIMAGE_FORMAT_JPG)
            return;

        NSFile::CFileBinary oFile;
        if (!oFile.OpenFile(wsFileName))
            return;

        if (20 > oFile.GetFileSize())
            return;

        BYTE data[20];
        DWORD dwRead = 0;
        if (!oFile.ReadFile(data, 20, dwRead))
            return;

        std::string sFind((char*)data, 20);
        oFile.CloseFile();

        if (std::string::npos == sFind.find("Photoshop") && std::string::npos == sFind.find("photoshop"))
            return;

        CBgraFrame oFrame;
        if (!oFrame.OpenFile(wsFileName))
            return;

        oFrame.SetJpegQuality(85.0);
        if (!oFrame.Encode(pBuffer, nBufferSize, _CXIMAGE_FORMAT_JPG))
            return;

        if (!pBuffer || !nBufferSize)
            return;

        unWidth = (unsigned int)oFrame.get_Width();
        unHeight = (unsigned int)oFrame.get_Height();
    }
示例#2
0
CString CPop3Message::GetHeaderItem(const CString& sName, int nItem) const
{
	//Value which will be returned by this function
	CString sField;
	
	//Get the message header (add an extra "\r\n" at the
	//begining to aid in the parsing)  
	CString sHeader(_T("\r\n"));
	sHeader += GetHeader();
	CString sUpCaseHeader(sHeader);
	sUpCaseHeader.MakeUpper();
	
	CString sUpCaseName(sName);
	sUpCaseName.MakeUpper();
	
	//Find the specified line in the header
	CString sFind(CString(_T("\r\n")) + sUpCaseName + _T(":"));
	int nFindLength = sFind.GetLength();
	int nFindStart = sUpCaseHeader.Find(sFind);
	int nFind = nFindStart;
	for (int i=0; i<nItem; i++) 
	{
		//Get ready for the next loop around
		sUpCaseHeader = sUpCaseHeader.Right(sUpCaseHeader.GetLength() - nFind - nFindLength);
		nFind = sUpCaseHeader.Find(sFind);
		
		if (nFind == -1)
			return _T(""); //Not found
		else
			nFindStart += (nFind + nFindLength);
	}
	
	if (nFindStart != -1)
		nFindStart += (3 + sName.GetLength());
	if (nFindStart != -1)
	{
		BOOL bFoundEnd = FALSE;
		int i = nFindStart;
		int nLength = sHeader.GetLength();
		do
		{
			//Examine the current 3 characters
			TCHAR c1 = _T('\0');
			if (i < nLength)
				c1 = sHeader[i];
			TCHAR c2 = _T('\0');
			if (i < (nLength-1))
				c2 = sHeader[i+1];
			TCHAR c3 = _T('\0');
			if (i < (nLength-2))
				c3 = sHeader[i+2];
			
			//Have we found the terminator
			if ((c1 == _T('\0')) ||
				((c1 == _T('\r')) && (c2 == _T('\n')) && (c3 != _T(' ')) && c3 != _T('\t')))
			{
				bFoundEnd = TRUE;
			}
			else
			{
				//Move onto the next character  
				++i;
			}
		}
		while (!bFoundEnd);
		sField = sHeader.Mid(nFindStart, i - nFindStart);
		
		//Remove any embedded "\r\n" sequences from the field
		int nEOL = sField.Find(_T("\r\n"));
		while (nEOL != -1)
		{
			sField = sField.Left(nEOL) + sField.Right(sField.GetLength() - nEOL - 2);
			nEOL = sField.Find(_T("\r\n"));
		}
		
		//Replace any embedded "\t" sequences with spaces
		int nTab = sField.Find(_T('\t'));
		while (nTab != -1)
		{
			sField = sField.Left(nTab) + _T(' ') + sField.Right(sField.GetLength() - nTab - 1);
			nTab = sField.Find(_T('\t'));
		}
		
		//Remove any leading or trailing white space from the Field Body
		sField.TrimLeft();
		sField.TrimRight();
	}
	
	return sField;
}
示例#3
0
ACStatement *ACDoc::_Statement()
{

  ACStatement *stat = NewStat();

  if(Scan.IfToken(';'))
  {
    stat->Op = ACS_EMPTY;
  }
  else if(Scan.Token == '{')
  {
    stat->Op = ACS_BLOCK;
    stat->Body = _Block();
  }
  else if(Scan.IfToken(AC_TOK_RETURN))
  {
    stat->Op = ACS_RETURN;
    if(Scan.Token!=';')
      stat->Expr = _Expression();
    Scan.Match(';');
  }
  else if(Scan.IfToken(AC_TOK_BREAK))
  {
    stat->Op = ACS_BREAK;
    Scan.Match(';');
  }
  else if(Scan.IfToken(AC_TOK_CONTINUE))
  {
    stat->Op = ACS_CONTINUE;
    Scan.Match(';');
  }
  else if(Scan.IfToken(AC_TOK_ASM))
  {
    sTextBuffer tb;
    Scan.ScanRaw(tb,'{','}');
    Scan.Match(';');

    stat->Op = ACS_ASM;
    stat->Expr = NewExpr(ACS_ASM,0,0);
    stat->Expr->Literal = Pool->Alloc<ACLiteral>();
    sClear(*stat->Expr->Literal);
    stat->Expr->Literal->Token = AC_TOK_ASM;
    stat->Expr->Literal->Value = tb.Get();
  }
  else if(Scan.Token=='[')
  {
    sTextBuffer tb;
    Scan.ScanRaw(tb,'[',']');

    stat->Op = ACS_ATTRIBUTE;
    stat->Expr = NewExpr(ACS_ATTRIBUTE,0,0);
    stat->Expr->Literal = Pool->Alloc<ACLiteral>();
    sClear(*stat->Expr->Literal);
    stat->Expr->Literal->Token = '[';
    stat->Expr->Literal->Value = tb.Get();
  }
  else if(Scan.IfToken(AC_TOK_IF))
  {
    stat->Op = ACS_IF;
    Scan.Match('(');
    stat->Cond = _Expression();
    Scan.Match(')');
    stat->Body = _Block();
    if(Scan.IfToken(AC_TOK_ELSE))
      stat->Else = _Statement();
  }
  else if(Scan.IfToken(AC_TOK_PIF))
  {
    stat->Op = ACS_PIF;
    Scan.Match('(');
    stat->Cond = _Expression();
    Scan.Match(')');
    stat->Body = _Block();
    if(Scan.IfToken(AC_TOK_PELSE))
      stat->Else = _Statement();
  }
  else if(Scan.IfToken(AC_TOK_WHILE))
  {
    stat->Op = ACS_WHILE;
    Scan.Match('(');
    stat->Cond = _Expression();
    Scan.Match(')');
    stat->Body = _Block();
  }
  else if(Scan.IfToken(AC_TOK_DO))
  {
    stat->Op = ACS_DO;
    stat->Body = _Block();
    Scan.Match(AC_TOK_WHILE);
    Scan.Match('(');
    stat->Cond = _Expression();
    Scan.Match(')');
    Scan.Match(';');
  }
  else if(Scan.IfToken(AC_TOK_FOR))
  {
    stat->Op = ACS_FOR;
    Scan.Match('(');
    stat->Else = _Statement();
    if(!(stat->Else->Op==ACS_VARDECL || stat->Else->Op==ACS_EXPRESSION))
      Scan.Error(L"first for argument must be a variable declaration or an expression");
    stat->Cond = _Expression();
    Scan.Match(';');
    stat->Expr = _Expression();
    Scan.Match(')');
    stat->Body = _Block();
  }
  else if(_IsDecl())
  {
    stat->Op = ACS_VARDECL;
    stat->Var = _Decl();
    if(stat->Var)
    {
      if(Scan.IfToken('='))
      {
        stat->Expr = _Expression();
      }
      if(sFind(Function->Locals[Scope],&ACVar::Name,stat->Var->Name))
        Scan.Error(L"local %q defined twice",stat->Var->Name);
      Function->Locals[Scope].AddTail(stat->Var);
      ACStatement **patch = &stat->Next;
      while(Scan.IfToken(','))
      {
        ACStatement *next = NewStat();

        next->Op = ACS_VARDECL;
        next->Var = _DeclPost(stat->Var->Type,stat->Var->Usages);
        
        if(sFind(Function->Locals[Scope],&ACVar::Name,next->Var->Name))
          Scan.Error(L"local %q defined twice",next->Var->Name);
        Function->Locals[Scope].AddTail(next->Var);

        *patch = next;
        patch = &next->Next;
      }
    }
    else
    {
      Scan.Error(L"nested type declarations not supported");
    }
    Scan.Match(';');
  }
  else
  {
    stat->Op = ACS_EXPRESSION;
    stat->Expr = _Expression();
    Scan.Match(';');
  }

  return stat;
}
示例#4
0
ACExpression *ACDoc::_Value()
{
  if(Scan.IfToken('+'))
    return NewExpr(ACE_POSITIVE,_Value(),0);
  if(Scan.IfToken('-'))
    return NewExpr(ACE_NEGATIVE,_Value(),0);
  if(Scan.IfToken('~'))
    return NewExpr(ACE_COMPLEMENT,_Value(),0);
  if(Scan.IfToken('!'))
    return NewExpr(ACE_NOT,_Value(),0);

  ACExpression *e = NewExpr(0,0,0);

  if(Scan.IfToken(AC_TOK_TRUE))
  {
    e->Op = ACE_TRUE;
  }
  else if(Scan.IfToken(AC_TOK_FALSE))
  {
    e->Op = ACE_FALSE;
  }
  else if(Scan.IfName(L"RENDER_DX9"))
  {
    e->Op = ACE_RENDER;
    e->Literal = Pool->Alloc<ACLiteral>();
    sClear(*e->Literal);
    e->Literal->Token = sTOK_INT;
    e->Literal->ValueI = sRENDER_DX9;
    e->Literal->ValueF = e->Literal->ValueI;
  }
  else if(Scan.IfName(L"RENDER_DX11"))
  {
    e->Op = ACE_RENDER;
    e->Literal = Pool->Alloc<ACLiteral>();
    sClear(*e->Literal);
    e->Literal->Token = sTOK_INT;
    e->Literal->ValueI = sRENDER_DX11;
    e->Literal->ValueF = e->Literal->ValueI;
  }
  else if(Scan.IfName(L"RENDER_OGL2"))
  {
    e->Op = ACE_RENDER;
    e->Literal = Pool->Alloc<ACLiteral>();
    sClear(*e->Literal);
    e->Literal->Token = sTOK_INT;
    e->Literal->ValueI = sRENDER_OGL2;
    e->Literal->ValueF = e->Literal->ValueI;
  }
  else if(Scan.Token==sTOK_NAME)
  {
    sPoolString name;
    ACVar *var;
    ACType *type;
    ACPermuteMember *mem;

    Scan.ScanName(name);

    type = FindType(name);
    if(type)
    {
      e->Op = ACE_CONSTRUCT;
      e->CastType = type;
      _ParameterList(&e->Left);
    }
    else
    {
      var = FindFunc(name);
      if(!var)
        var = FindVar(name);
      if(var)
      {
        e->Op = ACE_VAR;
        e->Variable = var;
      }
      else
      {
        mem = 0;
        if(UsePermute)
          mem = sFind(UsePermute->Members,&ACPermuteMember::Name,name);
        if(mem)
        {
          e->Op = ACE_PERMUTE;
          e->Permute = mem;
        }
        else
        {
          Scan.Error(L"unkown symbol %q",name);
        }
      }
    }
  }
  else if(Scan.Token==sTOK_INT)
  {
    e->Op = ACE_LITERAL;
    e->Literal = Pool->Alloc<ACLiteral>();
    sClear(*e->Literal);
    e->Literal->Token = sTOK_INT;
    e->Literal->Value = Scan.ValueString;
    e->Literal->ValueI = Scan.ValI;
    e->Literal->ValueF = e->Literal->ValueI;
    Scan.Scan();
  }
  else if(Scan.Token==sTOK_FLOAT)
  {
    e->Op = ACE_LITERAL;
    e->Literal = Pool->Alloc<ACLiteral>();
    sClear(*e->Literal);
    e->Literal->Token = sTOK_FLOAT;
    e->Literal->Value = Scan.ValueString;
    e->Literal->ValueF = Scan.ValF;
    e->Literal->ValueI = e->Literal->ValueF;
    Scan.Scan();
  }
  else if(Scan.Token=='{')
  {
    e->Op = ACE_LITERAL;
    e->Literal = _Literal();
  }
  else if(Scan.Token=='(')
  {
    Scan.Match('(');
    ACType *ctype = 0;
    if(Scan.Token==sTOK_NAME)
      ctype = FindType(Scan.Name);

    if(ctype && Scan.DirtyPeek()==')')
    {
      Scan.Scan();
      Scan.Match(')');
      e->Op = ACE_CAST;
      e->CastType = ctype;
      e->Left = _Expression();
      return e;                         // this is handled like a prefix operator!
    }
    else
    {
      e = _Expression();
      Scan.Match(')');
    }
  }
  else
  {
    Scan.Error(L"value expected");
  }

postfix:
  if(Scan.IfToken('['))
  {
    e = NewExpr(ACE_INDEX,e,_Expression());
    Scan.Match(']');
    goto postfix;
  }
  if(Scan.IfToken('.'))
  {
    e = NewExpr(ACE_MEMBER,e,0);
    Scan.ScanName(e->Member);
    goto postfix;
  }
  if(Scan.IfToken(AC_TOK_INC))
  {
    e = NewExpr(ACE_POSTINC,e,0);
    goto postfix;
  }
  if(Scan.IfToken(AC_TOK_DEC))
  {
    e = NewExpr(ACE_POSTDEC,e,0);
    goto postfix;
  }
  if(Scan.Token=='(')
  {
    if((e->Op==ACE_VAR && e->Variable->Function))
    {
      e->Op = ACE_CALL;
      _ParameterList(&e->Left);
    }
    else if(e->Op==ACE_MEMBER && e->Member)
    {
      e->Right = NewExpr(ACE_CALL,0,0);
      _ParameterList(&e->Right->Left);
    }
    else
    {
      Scan.Error(L"you can only call() functions and members");
      ACExpression *dummy = NewExpr(ACE_CALL,0,0);
      _ParameterList(&dummy->Left);
    }
    goto postfix;
  }

  return e;
}
示例#5
0
ACVar *ACDoc::_DeclPost(ACType *type,sInt usages)
{
  ACVar *var;
  sPoolString test;
  sPoolString name;

// name

  Scan.ScanName(name);

// array

  while(Scan.IfToken('['))
  {
    ACType *t2 = new ACType;
    t2->BaseType = type;
    t2->ArrayCountExpr = _Expression();
    if(t2->ArrayCountExpr->Op == ACE_LITERAL && t2->ArrayCountExpr->Literal->Token==sTOK_INT)
      t2->ArrayCount = t2->ArrayCountExpr->Literal->ValueI;
    t2->Type = ACT_ARRAY;
    UserTypes.AddTail(t2);
    type = t2;
    Scan.Match(']');
  }

// func
    
  if(Scan.IfToken('('))
  {
    ACFunc *func = new ACFunc;
    var = func;
    sBool first = 1;
    while(Scan.Errors==0 && Scan.Token!=')')
    {
      if(!first)
        Scan.Match(',');
      first = 0;
      if(Scan.Token==')')                     // EXTENSION (allow trailing , in parameter list)
        break;

      ACVar *member = _Decl();
      if(member)
      {
        if(sFind(func->Locals[SCOPE_PARA],&ACVar::Name,member->Name))
          Scan.Error(L"parameter %q defined twice",member->Name);
        func->Locals[SCOPE_PARA].AddTail(member);
      }
      else
        Scan.Error(L"nested type declarations not supported");
    }
    Scan.Match(')');
  }
  else
  {
    var = new ACVar;
    AllVariables.AddTail(var);
  }

// semantics

  while(Scan.IfToken(':'))
  {
    if(Scan.Token==AC_TOK_REGISTER)
    {
      if(var->RegisterType)
        Scan.Error(L"more than one register binding for %q",name);
      _Register(var->RegisterType,var->RegisterNum);
    }
    else if(Scan.Token==AC_TOK_PIF)           // EXTENSION (permutation dependend declarations)
    {
      Scan.Match(AC_TOK_PIF);
      Scan.Match('(');
      var->Permute = _Expression();
      Scan.Match(')');
    }
    else
    {
      if(!var->Semantic.IsEmpty())
        Scan.Error(L"more than one semantic for %q",name);
      Scan.ScanName(var->Semantic);
    }
  }

  var->Name = name;
  var->Type = type;
  var->Usages = usages;
  return var;
}
示例#6
0
ACVar *ACDoc::_Decl()
{
  sPoolString test;
  ACType *type = 0;
  sInt usages = 0;

// usages and flags

usages_:
  if(Scan.Token==AC_TOK_IN)       { usages |= ACF_IN; Scan.Scan(); goto usages_; }
  if(Scan.Token==AC_TOK_OUT)      { usages |= ACF_OUT; Scan.Scan(); goto usages_; }
  if(Scan.Token==AC_TOK_INOUT)    { usages |= ACF_INOUT; Scan.Scan(); goto usages_; }
  if(Scan.Token==AC_TOK_UNIFORM)  { usages |= ACF_UNIFORM; Scan.Scan(); goto usages_; }
  if(Scan.Token==AC_TOK_ROWMAJOR) { usages |= ACF_ROWMAJOR; Scan.Scan(); goto usages_; }
  if(Scan.Token==AC_TOK_COLMAJOR) { usages |= ACF_COLMAJOR; Scan.Scan(); goto usages_; }
  if(Scan.Token==AC_TOK_CONST)    { usages |= ACF_CONST; Scan.Scan(); goto usages_; }
  if(Scan.Token==AC_TOK_INLINE)   { usages |= ACF_INLINE; Scan.Scan(); goto usages_; }
  if(Scan.Token==AC_TOK_STATIC)   { usages |= ACF_STATIC; Scan.Scan(); goto usages_; }
  if(Scan.Token==AC_TOK_GROUPSHARED) { usages |= ACF_GROUPSHARED; Scan.Scan(); goto usages_; }

  if(Scan.IfName(L"point"))       { usages |= ACF_POINT; goto usages_; }
  if(Scan.IfName(L"line"))        { usages |= ACF_LINE; goto usages_; }
  if(Scan.IfName(L"triangle"))    { usages |= ACF_TRIANGLE; goto usages_; }
  if(Scan.IfName(L"lineadj"))     { usages |= ACF_LINEADJ; goto usages_; }
  if(Scan.IfName(L"triangleadj")) { usages |= ACF_TRIANGLEADJ;  goto usages_; }

// struct

  if(Scan.Token==AC_TOK_STRUCT)
  {
    Scan.Scan();
    type = _Struct(ACT_STRUCT);
    if(sFind(UserTypes,&ACType::Name,type->Name))
      Scan.Error(L"type %q defined twice",type->Name);
    UserTypes.AddTail(type);
    return 0;
  }
  else if(Scan.Token==AC_TOK_CBUFFER)           // EXTENSION
  {
    Scan.Scan();
    ACType *type = _Struct(ACT_CBUFFER);
    if(sFind(UserTypes,&ACType::Name,type->Name))
      Scan.Error(L"type %q defined twice",type->Name);
    UserTypes.AddTail(type);
    return 0;
  }
  else // type
  {
    Scan.ScanName(test);
    type = FindType(test);
    if(!type)
      Scan.Error(L"unknown type %q",test);
    if(Scan.IfToken('<'))
    {
      sPoolString name;
      Scan.ScanName(name);      
      type->Template = FindType(name);
      if(type->Template == 0 && !Scan.Errors)
        Scan.Error(L"unknown type %q in template parameter",name);
      if(Scan.IfToken(','))
        type->TemplateCount = Scan.ScanInt();
      Scan.Match('>');
    }
  }

// name and restdone

  return _DeclPost(type,usages);
}
示例#7
0
void ACDoc::_Permute()
{
  ACPermute *perm;
  ACPermuteMember *mem;
  Scan.Match(AC_TOK_PERMUTE);
  sPoolString groupname;
  sInt shift;
  sInt num;
  sInt power;
  ACPermute *OldUse = UsePermute;

  perm = new ACPermute;
  UsePermute = perm;
  Scan.ScanName(perm->Name);
  Scan.Match('{');

  shift = 0;

  while(!Scan.Errors && Scan.Token!='}')
  {
    if(Scan.IfToken(AC_TOK_ASSERT))
    {
      Scan.Match('(');
      perm->Asserts.AddTail(_Expression());
      Scan.Match(')');
      Scan.Match(';');
    }
    else
    {
      num = 0;
      Scan.ScanName(groupname);
      if(Scan.IfToken('{'))
      {
        while(!Scan.Errors && Scan.Token!='}')
        {
          mem = perm->Members.AddMany(1);
          mem->Group = 0;
          Scan.ScanName(mem->Name);
          mem->Value = num++;
          mem->Shift = shift;
          mem->Mask = 0;
          if(Scan.Token!='}')
            Scan.Match(',');
        }
        Scan.Match('}');
      }
      else
      {
        num = 2;
      }
      Scan.Match(';');
      mem = perm->Members.AddMany(1);
      mem->Group = 1;
      mem->Name = groupname;
      mem->Value = 0;
      mem->Max = num;
      mem->Shift = shift;
      power = sFindHigherPower(num-1)+1;
      mem->Mask = (1<<power)-1;
      shift += power;
    }
  }

  Scan.Match('}');
  Scan.Match(';');

  perm->MaxShift = shift;

  if(sFind(Permutes,&ACPermute::Name,perm->Name))
    Scan.Error(L"permutation %q defined twice",perm->Name);
  Permutes.AddTail(perm);
  UsePermute = OldUse;
}
示例#8
0
ACType *ACDoc::_Struct(sInt typekind)      // 'struct' already scanned
{
  ACType *type = new ACType;
  type->Type = typekind;
  if(Scan.Token==sTOK_NAME)
    Scan.ScanName(type->Name);

  sInt constreg = -1;
  sInt constname = 0;

  while(Scan.IfToken(':'))                     // EXTENSION: auto constant registers
  {
    if(Scan.Token==AC_TOK_REGISTER)
    {
      _Register(constname,constreg);
      if(constname!='c')
        Scan.Error(L"constant register expected, found <%c%d>!",constname,constreg);
      type->CRegStart = constreg;
    }
    else if(Scan.Token==sTOK_NAME && Scan.Name==L"slot")
    {
      Scan.MatchName(L"slot");
      sPoolString shadertype;
      Scan.ScanName(shadertype);

      type->CSlot = Scan.ScanInt();
      if(type->CSlot<0 || type->CSlot>=sCBUFFER_MAXSLOT)
        Scan.Error(L"cbuffer slot out of range (max is %d)",(sInt)sCBUFFER_MAXSLOT);
      if(shadertype==L"vs")
        type->CSlot |= sCBUFFER_VS;
      else if(shadertype==L"hs")
        type->CSlot |= sCBUFFER_HS;
      else if(shadertype==L"ds")
        type->CSlot |= sCBUFFER_DS;
      else if(shadertype==L"gs")
        type->CSlot |= sCBUFFER_GS;
      else if(shadertype==L"ps")
        type->CSlot |= sCBUFFER_PS;
      else if(shadertype==L"cs")
        type->CSlot |= sCBUFFER_CS;
      else 
        Scan.Error(L"unknown shader type %q",shadertype);
    }
    else
    {
      Scan.Error(L"don't understand semantik");
    }
  }

  Scan.Match('{');
  while(!Scan.Errors && Scan.Token!='}')
  {
    if(Scan.Token==AC_TOK_EXTERN)
    {
      type->Externs.AddTail(_Extern());
    }
    else
    {
      ACVar *var = _Decl();
      if(sFind(type->Members,&ACVar::Name,var->Name))
        Scan.Error(L"member %q defined twice",var->Name);
      type->Members.AddTail(var);
      while(Scan.IfToken(','))
      {
        ACVar *var2 = _DeclPost(var->Type,var->Usages);
        if(sFind(type->Members,&ACVar::Name,var2->Name))
          Scan.Error(L"member %q defined twice",var2->Name);
        type->Members.AddTail(var2);
      }

      if(typekind==ACT_CBUFFER && (var->Usages & ~(ACF_ROWMAJOR|ACF_COLMAJOR)) )
        Scan.Error(L"usages not allowed in cbuffer");
      if(typekind==ACT_CBUFFER && !var->Semantic.IsEmpty())
        Scan.Error(L"semantics not allowed in cbuffer");
      if(constname && var->RegisterType)
        Scan.Error(L"automatic register binding and explicit register binding at the same time");
      if(constname)
      {
        var->RegisterType = 'c';
        var->RegisterNum = constreg;
        sInt c,r;
        var->Type->SizeOf(c,r);
        if((var->Usages & ACF_ROWMAJOR) && c>1 && r>1)
        {
          if(var->Type->Type==ACT_ARRAY)
          {
            // transpose before calculating array size
            var->Type->BaseType->SizeOf(c,r);
            sSwap(c,r);
            r = 4;
            if(var->Type->ArrayCount==0)
              Scan.Error(L"could not determine array count");
            c *= var->Type->ArrayCount;
          }
          else
            sSwap(c,r);
        }
        constreg += c;
      }
      Scan.Match(';');
    }
  }
  if(constname)
    type->CRegCount = constreg-type->CRegStart;

  Scan.Match('}');

  return type;
}
示例#9
0
void ACDoc::_Global()
{
  ACGlobal *gl;
  ACPermute *perm;
  while(Scan.Errors==0 && Scan.Token!=sTOK_END)
  {
    if(Scan.IfToken(AC_TOK_LINE))
    {
      _Line();
    }
    else if(Scan.IfToken(AC_TOK_USE))             // EXTENSION: use cbuffer & permutes
    {
      sPoolString name;
      Scan.ScanName(name);

      perm = sFind(Permutes,&ACPermute::Name,name);    // use permutes
      if(perm)
      {
        if(UsePermute)
          Scan.Error(L"permute can be used only once");
        else
          UsePermute = perm;
        Scan.Match(';');
      }
      else                                          // use cbuffer
      {
        gl = Program.AddMany(1);
        sClear(*gl);
        gl->SourceLine = Scan.TokenLine;
        gl->SourceFile = Scan.TokenFile;
        gl->Kind = ACG_USE;
        gl->Type = FindType(name);
        Scan.Match(';');
        if(!gl->Type)
        {
          Scan.Error(L"type %q not found",name);
        }
        else
        {
          if(gl->Type->Type==ACT_CBUFFER)
          {
            // use cbuffer

            Variables.Add(gl->Type->Members);
  //          gl->Type->Members.Clear();
          }
          else
          {
            Scan.Error(L"cbuffer expected in use clause");
          }
        }
      }
    }
    else if(Scan.Token=='[')
    {
      sTextBuffer tb;
      Scan.ScanRaw(tb,'[',']');

      gl = Program.AddMany(1);
      sClear(*gl);
      gl->SourceLine = Scan.TokenLine;
      gl->SourceFile = Scan.TokenFile;
      gl->Kind = ACG_ATTRIBUTE;
      gl->Attribute = tb.Get();
      if(Scan.IfToken(':'))
      {
        Scan.Match(AC_TOK_PIF);
        Scan.Match('(');
        gl->Permute = _Expression();
        Scan.Match(')');
      }
    }
    else if(Scan.IfToken(AC_TOK_PRAGMA))
    {
      gl = Program.AddMany(1);
      sClear(*gl);
      gl->SourceLine = Scan.TokenLine;
      gl->SourceFile = Scan.TokenFile;
      gl->Kind = ACG_PRAGMA;
      Scan.ScanString(gl->Attribute);
      if(Scan.IfToken(':'))
      {
        Scan.Match(AC_TOK_PIF);
        Scan.Match('(');
        gl->Permute = _Expression();
        Scan.Match(')');
      }
      Scan.Match(';');
    }
    else if(Scan.Token==AC_TOK_PERMUTE)
    {
      _Permute();
    }
    else
    {      
      ACVar *var = _Decl();
      if(var==0)
      {
        ACType *type = UserTypes[UserTypes.GetCount()-1];
        if(type->Type!=ACT_CBUFFER)
        {
          gl = Program.AddMany(1);
          sClear(*gl);
          gl->SourceLine = Scan.TokenLine;
          gl->SourceFile = Scan.TokenFile;
          gl->Kind = ACG_TYPEDEF;
          gl->Type = type;
        }
        Scan.Match(';');
      }
      else if(var->Function && Scan.Token=='{')
      {
        ACFunc *func = (ACFunc *) var;
        sPoolString dummy;

        Function = func;
        Scope = 2;
        func->FuncBody = _Block();
        Function = 0;
        Scope = 0;

        if(sFind(Functions,&ACFunc::Name,var->Name))
          Scan.Error(L"function %q defined twice",var->Name);
        Functions.AddTail(func);

        gl = Program.AddMany(1);
        sClear(*gl);
        gl->SourceLine = Scan.TokenLine;
        gl->SourceFile = Scan.TokenFile;
        gl->Kind = ACG_FUNC;
        gl->Var = var;
      }
      else
      {
        if(var->Function)
          Scan.Error(L"function without body");
//        var->Usages |= ACF_UNIFORM;

        if(sFind(Variables,&ACVar::Name,var->Name))
          Scan.Error(L"global variable %q defined twice",var->Name);
        Variables.AddTail(var);

        gl = Program.AddMany(1);
        sClear(*gl);
        gl->SourceLine = Scan.TokenLine;
        gl->SourceFile = Scan.TokenFile;
        gl->Kind = ACG_VARIABLE;
        gl->Var = var;

        if(Scan.IfToken('='))
          gl->Init = _Expression();
        Scan.Match(';');
      }
    }
  }
}