static uint8_t prvTraceUserEventFormat()

in FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c [858:1007]


static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_t* buffer, uint8_t byteOffset)
{
	uint16_t formatStrIndex = 0;
	uint8_t argCounter = 0;
	uint8_t i = byteOffset;

	while (formatStr[formatStrIndex] != '\0')
	{
		if (formatStr[formatStrIndex] == '%')
		{
			if (formatStr[formatStrIndex + 1] == '%')
			{
				formatStrIndex += 2;
				continue;
			}

			/* We found a possible argument */
			argCounter++;

			formatStrIndex++;

			while ((formatStr[formatStrIndex] >= '0' && formatStr[formatStrIndex] <= '9') || formatStr[formatStrIndex] == '#' || formatStr[formatStrIndex] == '.')
				formatStrIndex++;

			/* This check is necessary to avoid moving past end of string. */
			if (formatStr[formatStrIndex] != '\0')
			{
				switch (formatStr[formatStrIndex])
				{
					case 'd':
						i = writeInt32(	buffer,
										i,
										(uint32_t)va_arg(vl, uint32_t));
						break;
					case 'x':
					case 'X':
					case 'u':
						i = writeInt32(	buffer,
										i,
										(uint32_t)va_arg(vl, uint32_t));
						break;
					case 's':
						i = writeInt16(	buffer,
										i,
										xTraceRegisterString((char*)va_arg(vl, char*)));
						break;

#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT)
					/* Yes, "double" as type also in the float
					case. This since "float" is promoted into "double"
					by the va_arg stuff. */
					case 'f':
						i = writeFloat(	buffer,
										i,
										(float)va_arg(vl, double));
						break;
#else
					/* No support for floats, but attempt to store a float user event
					avoid a possible crash due to float reference. Instead store the
					data on uint_32 format (will not be displayed anyway). This is just
					to keep va_arg and i consistent. */

					case 'f':
						i = writeInt32(	buffer,
										i,
										(uint32_t)va_arg(vl, double));
						break;
#endif
					case 'l':
						formatStrIndex++;
						switch (formatStr[formatStrIndex])
						{
#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT)
							case 'f':	i = writeDouble(buffer,
														i,
														(double)va_arg(vl, double));
								break;
#else
							/* No support for floats, but attempt to store a float user event
							avoid a possible crash due to float reference. Instead store the
							data on uint_32 format (will not be displayed anyway). This is just
							to keep va_arg and i consistent. */
							case 'f':
								i = writeInt32(	buffer, /* In this case, the value will not be shown anyway */
												i,
												(uint32_t)va_arg(vl, double));

								i = writeInt32(	buffer, /* Do it twice, to write in total 8 bytes */
												i,
												(uint32_t)va_arg(vl, double));
								break;
#endif
						}
						break;
					case 'h':
						formatStrIndex++;
						switch (formatStr[formatStrIndex])
						{
							case 'd':
								i = writeInt16(	buffer,
												i,
												(uint16_t)va_arg(vl, uint32_t));
								break;
							case 'u':
								i = writeInt16(	buffer,
												i,
												(uint16_t)va_arg(vl, uint32_t));
								break;
						}
						break;
					case 'b':
						formatStrIndex++;
						switch (formatStr[formatStrIndex])
						{
							case 'd':
								i = writeInt8(	buffer,
												i,
												(uint8_t)va_arg(vl, uint32_t));
								break;
							case 'u':
								i = writeInt8(	buffer,
												i,
												(uint8_t)va_arg(vl, uint32_t));
								break;
						}
						break;
					default:
						/* False alarm: this wasn't a valid format specifier */
						argCounter--;
						break;
				}

				if (argCounter > 15)
				{
					prvTraceError("vTracePrintF - Too many arguments, max 15 allowed!");
					return 0;
				}
			}
			else
				break;
		}
		formatStrIndex++;
		if (i == 255)
		{
			prvTraceError("vTracePrintF - Too large arguments, max 32 byte allowed!");
			return 0;
		}
	}
	return (uint8_t)(i+3)/4;
}