コード例 #1
0
void VInvocation::CheckDecorateParams(VEmitContext& ec)
{
	guard(VInvocation::CheckDecorateParams);
	int max_params;
	int num_needed_params = Func->NumParams;
	if (Func->Flags & FUNC_VarArgs)
	{
		max_params = VMethod::MAX_PARAMS - 1;
	}
	else
	{
		max_params = Func->NumParams;
	}
	if (NumArgs > max_params)
	{
		ParseError(Loc, "Incorrect number of arguments, need %d, got %d.", max_params, NumArgs);
	}

	for (int i = 0; i < NumArgs; i++)
	{
		if (i >= num_needed_params)
		{
			continue;
		}
		if (!Args[i])
		{
			continue;
		}
		switch (Func->ParamTypes[i].Type)
		{
		case TYPE_Name:
			if (Args[i]->IsDecorateSingleName())
			{
				VDecorateSingleName* E = (VDecorateSingleName*)Args[i];
				Args[i] = new VNameLiteral(*E->Name, E->Loc);
				delete E;
				E = NULL;
			}
			else if (Args[i]->IsStrConst())
			{
				VStr Val = Args[i]->GetStrConst(ec.Package);
				TLocation ALoc = Args[i]->Loc;
				delete Args[i];
				Args[i] = NULL;
				Args[i] = new VNameLiteral(*Val, ALoc);
			}
			break;

		case TYPE_String:
			if (Args[i]->IsDecorateSingleName())
			{
				VDecorateSingleName* E = (VDecorateSingleName*)Args[i];
				Args[i] = new VStringLiteral(ec.Package->FindString(*E->Name), E->Loc);
				delete E;
				E = NULL;
			}
			break;

		case TYPE_Class:
			if (Args[i]->IsDecorateSingleName())
			{
				VDecorateSingleName* E = (VDecorateSingleName*)Args[i];
				Args[i] = new VStringLiteral(ec.Package->FindString(*E->Name), E->Loc);
				delete E;
				E = NULL;
			}
			if (Args[i]->IsStrConst())
			{
				VStr CName = Args[i]->GetStrConst(ec.Package);
				TLocation ALoc = Args[i]->Loc;
				VClass* Cls = VClass::FindClassNoCase(*CName);
				if (!Cls)
				{
					ParseWarning(ALoc, "No such class %s", *CName);
					delete Args[i];
					Args[i] = NULL;
					Args[i] = new VNoneLiteral(ALoc);
				}
				else if (Func->ParamTypes[i].Class &&
					!Cls->IsChildOf(Func->ParamTypes[i].Class))
				{
					ParseWarning(ALoc, "Class %s is not a descendant of %s",
						*CName, Func->ParamTypes[i].Class->GetName());
					delete Args[i];
					Args[i] = NULL;
					Args[i] = new VNoneLiteral(ALoc);
				}
				else
				{
					delete Args[i];
					Args[i] = NULL;
					Args[i] = new VClassConstant(Cls, ALoc);
				}
			}
			break;

		case TYPE_State:
			if (Args[i]->IsIntConst())
			{
				int Offs = Args[i]->GetIntConst();
				TLocation ALoc = Args[i]->Loc;
				if (Offs < 0)
				{
					ParseError(ALoc, "Negative state jumps are not allowed");
				}
				else if (Offs == 0)
				{
					//	0 means no state
					delete Args[i];
					Args[i] = NULL;
					Args[i] = new VNoneLiteral(ALoc);
				}
				else
				{
					check(CallerState);
					VState* S = CallerState->GetPlus(Offs, true);
					if (!S)
					{
						ParseError(ALoc, "Bad state jump offset");
					}
					else
					{
						delete Args[i];
						Args[i] = NULL;
						Args[i] = new VStateConstant(S, ALoc);
					}
				}
			}
			else if (Args[i]->IsStrConst())
			{
				VStr Lbl = Args[i]->GetStrConst(ec.Package);
				TLocation ALoc = Args[i]->Loc;
				int DCol = Lbl.IndexOf("::");
				if (DCol >= 0)
				{
					//	Jump to a specific parent class state, resolve it and
					// pass value directly.
					VStr ClassName(Lbl, 0, DCol);
					VClass* CheckClass;
					if (ClassName.ICmp("Super"))
					{
						CheckClass = ec.SelfClass->ParentClass;
					}
					else
					{
						CheckClass = VClass::FindClassNoCase(*ClassName);
						if (!CheckClass)
						{
							ParseError(ALoc, "No such class %s", *ClassName);
						}
						else if (!ec.SelfClass->IsChildOf(CheckClass))
						{
							ParseError(ALoc, "%s is not a subclass of %s",
								ec.SelfClass->GetName(), CheckClass->GetName());
							CheckClass = NULL;
						}
					}
					if (CheckClass)
					{
						VStr LblName(Lbl, DCol + 2, Lbl.Length() - DCol - 2);
						TArray<VName> Names;
						VMemberBase::StaticSplitStateLabel(LblName, Names);
						VStateLabel* StLbl = CheckClass->FindStateLabel(Names, true);
						if (!StLbl)
						{
							ParseError(ALoc, "No such state %s", *Lbl);
						}
						else
						{
							delete Args[i];
							Args[i] = NULL;
							Args[i] = new VStateConstant(StLbl->State, ALoc);
						}
					}
				}
				else
				{
					//	It's a virtual state jump
					VExpression* TmpArgs[1];
					TmpArgs[0] = Args[i];
					Args[i] = new VInvocation(NULL,
						ec.SelfClass->FindMethodChecked("FindJumpState"),
						NULL, false, false, Args[i]->Loc, 1, TmpArgs);
				}
			}
			break;
		}
	}
	unguard;
}
コード例 #2
0
ファイル: Translator.cpp プロジェクト: asceth/synapi
SMCResult CPhraseFile::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
{
	/* See if we are ignoring a phrase */
	if (m_CurPhrase == -1)
	{
		return SMCResult_Continue;
	}

	phrase_t *pPhrase = (phrase_t *)m_pMemory->GetAddress(m_CurPhrase);

	/* Duplicate format keys get silently ignored. */
	if (key[0] == '#' 
		&& strcmp(key, "#format") == 0
		&& pPhrase->fmt_list == -1)
	{
		if (pPhrase->translations > 0)
		{
			ParseWarning("#format property should come before translations on line %d, ignoring", states->line);
			return SMCResult_Continue;
		}

		/* Do an initial browsing for error checking and what not */
		enum ParseStates
		{
			Parse_None,
			Parse_Index,
			Parse_Format,
		};

		ParseStates state = Parse_None;

		const char *old_value = value;
		const char *last_value = value;
		while (*value != '\0')
		{
			if (state == Parse_None)
			{
				if (*value == '{')
				{
					pPhrase->fmt_count++;
					state = Parse_Index;
				} 
				else if (*value == ',') 
				{
					/* Do nothing */
				} 
				else 
				{
					unsigned int bytes = textparsers->GetUTF8CharBytes(value);
					if (bytes != 1 || !isalpha(*value))
					{
						ParseWarning("Invalid token '%c' in #format property on line %d.", *value, states->line);
					}
				}
			} 
			else if (state == Parse_Index) 
			{
				if (*value == ':')
				{
					state = Parse_Format;
					if (value - last_value >= 15)
					{
						ParseWarning("Too many digits in format index on line %d, phrase will be ignored.", states->line);
						m_CurPhrase = -1;
						return SMCResult_Continue;
					}
				} 
				else 
				{
					unsigned int bytes = textparsers->GetUTF8CharBytes(value);
					if (bytes != 1 || !isdigit(*value))
					{
						ParseWarning("Token '%c' in #format property on line %d is not a digit, phrase will be ignored.",
									*value,
									states->line);
						m_CurPhrase = -1;
						return SMCResult_Continue;
					}
				}
			} 
			else if (state == Parse_Format) 
			{
				if (*value == '}')
				{
					state = Parse_None;
					last_value = value + 1;
				}
			}
			value++;
		}

		if (state != Parse_None)
		{
			/* Moose clam cow. */
			ParseWarning("Unterminated format string on line %d, phrase will be ignored.", states->line);
			m_CurPhrase = -1;
			return SMCResult_Continue;
		}
		value = old_value;

		/* Allocate the format table */
		char fmt_buf[16];
		int *fmt_list;
		int tmp = m_pMemory->CreateMem(sizeof(int) * pPhrase->fmt_count, (void **)&fmt_list);

		/* Update the phrase pointer in case it changed */
		pPhrase = (phrase_t *)m_pMemory->GetAddress(m_CurPhrase);
		pPhrase->fmt_list = tmp;

		/* Initialize */
		for (size_t i=0; i<pPhrase->fmt_count; i++)
		{
			fmt_list[i] = -1;
		}

		/* Now we need to read again... this time into the format buffer */
		const char *in_ptr = value;
		const char *idx_ptr = NULL;
		char *out_ptr = NULL;
		unsigned int cur_idx = 0;
		state = Parse_None;
		while (*in_ptr != '\0')
		{
			if (state == Parse_None)
			{
				if (*in_ptr == '{')
				{
					state = Parse_Index;
					idx_ptr = NULL;
				}
			}
			else if (state == Parse_Index) 
			{
				if (*in_ptr == ':')
				{
					/* Check the number! */
					if (!idx_ptr)
					{
						ParseWarning("Format property contains unindexed format string on line %d, phrase will be ignored.", states->line);
						m_CurPhrase = -1;
						return SMCResult_Continue;
					}
					long idx = strtol(idx_ptr, NULL, 10);
					if (idx < 1 || idx > (long)pPhrase->fmt_count)
					{
						ParseWarning("Format property contains invalid index '%d' on line %d, phrase will be ignored.", idx, states->line);
						m_CurPhrase = -1;
						return SMCResult_Continue;
					}
					else if (fmt_list[idx - 1] != -1) 
					{
						ParseWarning("Format property contains duplicated index '%d' on line %d, phrase will be ignored.", idx, states->line);
						m_CurPhrase = -1;
						return SMCResult_Continue;
					}
					cur_idx = (unsigned int)idx;
					state = Parse_Format;
					out_ptr = NULL;
				}
				else if (!idx_ptr) 
				{
					idx_ptr = in_ptr;
				}
			}
			else if (state == Parse_Format) 
			{
				if (*in_ptr == '}')
				{
					if (!out_ptr)
					{
						ParseWarning("Format property contains empty format string on line %d, phrase will be ignored.", states->line);
						m_CurPhrase = -1;
						return SMCResult_Continue;
					}
					*out_ptr = '\0';
					state = Parse_None;
					/* Now, add this to our table */
					int tmp_idx = m_pStringTab->AddString(fmt_buf);
					/* Update pointers and update necessary variables */
					pPhrase = (phrase_t *)m_pMemory->GetAddress(m_CurPhrase);
					pPhrase->fmt_bytes += strlen(fmt_buf);
					fmt_list = (int *)m_pMemory->GetAddress(pPhrase->fmt_list);
					fmt_list[cur_idx - 1] = tmp_idx;
				} 
				else 
				{
					if (!out_ptr)
					{
						out_ptr = fmt_buf;
						*out_ptr++ = '%';
					}
					/* Check length ... */
					if ((unsigned)(out_ptr - fmt_buf) >= sizeof(fmt_buf) - 1)
					{
						ParseWarning("Format property contains format string that exceeds maximum length on line %d, phrase will be ignored.",
									 states->line);
						m_CurPhrase = -1;
						return SMCResult_Continue;
					}
					*out_ptr++ = *in_ptr;
				}
			}
			in_ptr++;
		}

		/* If we've gotten here, we only accepted unique indexes in a range.
		 * Therefore, the list has to be completely filled.  Double check anyway.
		 */
		for (size_t i=0; i<pPhrase->fmt_count; i++)
		{
			if (fmt_list[i] == -1)
			{
				ParseWarning("Format property contains no string for index %d on line %d, phrase will be ignored.",
							 i + 1,
							 states->line);
				m_CurPhrase = -1;
				return SMCResult_Continue;
			}
		}
	} 
	else 
	{
		size_t len = strlen(key);
		if (len < 2 || len > 3)
		{
			ParseWarning("Ignoring translation to invalid language \"%s\" on line %d.", key, states->line);
			return SMCResult_Continue;
		}

		unsigned int lang;
		if (!m_pTranslator->GetLanguageByCode(key, &lang))
		{
			/* Ignore if we don't have a language.
			 * :IDEA: issue a one-time alert?
			 */
			return SMCResult_Continue;
		}

		/* See how many bytes we need for this string, then allocate.
		 * NOTE: THIS SHOULD GUARANTEE THAT WE DO NOT NEED TO NEED TO SIZE CHECK 
		 */
		len = strlen(value) + pPhrase->fmt_bytes + 1;
		char *out_buf;
		int out_idx;

		out_idx = m_pMemory->CreateMem(len, (void **)&out_buf);

		/* Update pointer */
		pPhrase = (phrase_t *)m_pMemory->GetAddress(m_CurPhrase);

		int *fmt_order;
		int *fmt_list = (int *)m_pMemory->GetAddress(pPhrase->fmt_list);
		trans_t *pTrans = (trans_t *)m_pMemory->GetAddress(pPhrase->trans_tbl);

		pTrans = &pTrans[lang];
		pTrans->stridx = out_idx;

		bool params[MAX_TRANSLATE_PARAMS];

		/* Build the format order list, if necessary */
		if (fmt_list)
		{
			int tmp = m_pMemory->CreateMem(pPhrase->fmt_count * sizeof(int), (void **)&fmt_order);
			
			/* Update pointers */
			pPhrase = (phrase_t *)m_pMemory->GetAddress(m_CurPhrase);
			pTrans = (trans_t *)m_pMemory->GetAddress(pPhrase->trans_tbl);
			fmt_list = (int *)m_pMemory->GetAddress(pPhrase->fmt_list);
			out_buf = (char *)m_pMemory->GetAddress(out_idx);
			pTrans = &pTrans[lang];

			/* Now it's safe to save the index */
			pTrans->fmt_order = tmp;

			for (unsigned int i=0; i<pPhrase->fmt_count; i++)
			{
				fmt_order[i] = -1;
			}
			memset(&params[0], 0, sizeof(params));
		}

		const char *in_ptr = value;
		char *out_ptr = out_buf;
		unsigned int order_idx = 0;
		while (*in_ptr != '\0')
		{
			if (*in_ptr == '\\')
			{
				switch (*(in_ptr + 1))
				{
				case '\n':
					*out_ptr++ = '\n';
					break;
				case '\t':
					*out_ptr++ = '\t';
					break;
				case '\r':
					*out_ptr++ = '\r';
					break;
				case '{':
					*out_ptr++ = '{';
					break;
				default:
					/* Copy both bytes since we don't know what's going on */
					*out_ptr++ = *in_ptr++;
					*out_ptr++ = *in_ptr;
					break;
				}
				/* Skip past the last byte read */
				in_ptr++;
			} 
			else if (*in_ptr == '{' && fmt_list != NULL) 
			{
				/* Search for parameters if this is a formatted string */
				const char *scrap_in_point = in_ptr;
				const char *digit_start = ++in_ptr;
				unsigned int bytes;
				while (*in_ptr != '\0')
				{
					bytes = textparsers->GetUTF8CharBytes(in_ptr);
					if (bytes != 1)
					{
						goto scrap_point;
					}
					if (*in_ptr == '}')
					{
						/* Did we get an index? */
						if (in_ptr == digit_start)
						{
							goto scrap_point;
						}
						/* Is it valid? */
						long idx = strtol(digit_start, NULL, 10);
						if (idx < 1 || idx > (int)pPhrase->fmt_count)
						{
							goto scrap_point;
						}
						if (params[idx-1])
						{
							goto scrap_point;
						}

						/* We're safe to insert the string.  First mark order. */
						fmt_order[order_idx++] = (int)idx - 1;
						/* Now concatenate */
						out_ptr += sprintf(out_ptr, "%s", m_pStringTab->GetString(fmt_list[idx-1]));
						/* Mark as used */
						params[idx-1] = true;

						goto cont_loop;
					}
					in_ptr++;
				}
scrap_point:
				/* Pretend none of this ever happened.  Move along now! */
				in_ptr = scrap_in_point;
				*out_ptr++ = *in_ptr;
			} else {
				*out_ptr++ = *in_ptr;
			}
cont_loop:
			in_ptr++;
		}
		*out_ptr = '\0';
		pPhrase->translations++;
	}

	return SMCResult_Continue;
}
コード例 #3
0
ファイル: decompile.c プロジェクト: Phonebooth/kannel
void Read_extension  (P_WBXML_INFO buffer)
{
	if (Is_switchPage(buffer))
	{
		Read_switchPage(buffer);
	}

	if (IsTag(buffer, TAG_EXT_I_0))
	{
		char* str = NULL;

		ReadFixedTag(buffer, TAG_EXT_I_0);
		Read_termstr_rtn(buffer, &str);

		AddVariableStringNode(buffer, str, VAR_ESCAPED); 
	}
	else if (IsTag(buffer, TAG_EXT_I_1))
	{
		char* str = NULL;

		ReadFixedTag(buffer, TAG_EXT_I_1);
		Read_termstr_rtn(buffer, &str);

		AddVariableStringNode(buffer, str, VAR_UNESCAPED); 
	}
	else if (IsTag(buffer, TAG_EXT_I_2))
	{
		char* str = NULL;

		ReadFixedTag(buffer, TAG_EXT_I_2);
		Read_termstr_rtn(buffer, &str);

		AddVariableStringNode(buffer, str, VAR_UNCHANGED); 
	}
	else if (IsTag(buffer, TAG_EXT_T_0))
	{
		WBXML_MB_U_INT32 index;

		ReadFixedTag(buffer, TAG_EXT_T_0);
		Read_index(buffer, &index);

		AddVariableIndexNode(buffer, index, VAR_ESCAPED);
	}
	else if (IsTag(buffer, TAG_EXT_T_1))
	{
		WBXML_MB_U_INT32 index;

		ReadFixedTag(buffer, TAG_EXT_T_1);
		Read_index(buffer, &index);

		AddVariableIndexNode(buffer, index, VAR_UNESCAPED);
	}
	else if (IsTag(buffer, TAG_EXT_T_2))
	{
		WBXML_MB_U_INT32 index;

		ReadFixedTag(buffer, TAG_EXT_T_2);
		Read_index(buffer, &index);

		AddVariableIndexNode(buffer, index, VAR_UNCHANGED);
	}
	else if (IsTag(buffer, TAG_EXT_0))
	{
		ReadFixedTag(buffer, TAG_EXT_0);

		ParseWarning(WARN_FUTURE_EXPANSION_EXT_0);
	}
	else if (IsTag(buffer, TAG_EXT_1))
	{
		ReadFixedTag(buffer, TAG_EXT_1);

		ParseWarning(WARN_FUTURE_EXPANSION_EXT_1);
	}
	else if (IsTag(buffer, TAG_EXT_2))
	{
		ReadFixedTag(buffer, TAG_EXT_2);

		ParseWarning(WARN_FUTURE_EXPANSION_EXT_2);
	}
	else
	{
		ParseError(ERR_TAG_NOT_FOUND);
	}
}
コード例 #4
0
ファイル: Translator.cpp プロジェクト: asceth/synapi
SMCResult CPhraseFile::ReadSMC_NewSection(const SMCStates *states, const char *name)
{
	bool recognized = false;
	if (m_ParseState == PPS_None)
	{
		if (strcmp(name, "Phrases") == 0)
		{
			m_ParseState = PPS_Phrases;
			recognized = true;
		}
	} 
	else if (m_ParseState == PPS_Phrases) 
	{
		m_ParseState = PPS_InPhrase;
		recognized = true;

		void *value;
		if (sm_trie_retrieve(m_pPhraseLookup, name, &value))
		{
			m_CurPhrase = reinterpret_cast<int>(value);
		}
		else
		{
			phrase_t *pPhrase;

			m_CurPhrase = m_pMemory->CreateMem(sizeof(phrase_t), (void **)&pPhrase);
			sm_trie_insert(m_pPhraseLookup, name, reinterpret_cast<void *>(m_CurPhrase));

			/* Initialize new phrase */
			trans_t *pTrans;

			pPhrase->fmt_count = 0;
			pPhrase->fmt_list = -1;

			int trans_tbl = m_pMemory->CreateMem(sizeof(trans_t) * m_LangCount, (void **)&pTrans);
			pPhrase = (phrase_t *)m_pMemory->GetAddress(m_CurPhrase);
			pPhrase->trans_tbl = trans_tbl;

			pPhrase->translations = 0;
			pPhrase->fmt_bytes = 0;

			for (unsigned int i=0; i<m_LangCount; i++)
			{
				pTrans[i].stridx = -1;
			}
		}

		m_LastPhraseString.assign(name);
	} 
	else if (m_ParseState == PPS_InPhrase) 
	{
		ParseError("Phrase sections may not have sub-sections");
		return SMCResult_HaltFail;
	}

	if (!recognized)
	{
		ParseWarning("Ignoring invalid section \"%s\" on line %d.", name, states->line);
	}

	return SMCResult_Continue;
}