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

📄 vheader.cpp

📁 将VHDL源文件中提取常量转换成C/C++的头文件。用于VHDL的固件和主机程序间的同步
💻 CPP
字号:
// vheader.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <windows.h>

#include <string.h>

#define MARK_DONTCARE	0
#define MARK_VHDL_CONST		1
#define MARK_VHDL_ASSIGN	2
#define MARK_VHDL_ENDTOKEN  3

#define ST_SEARCHING	1
#define ST_GET_NAME		2
#define ST_FIND_VALUE	3
#define ST_GET_VALUE	4

#define FOLDER_TOKEN '\\'

int single_file;

char * format_hex(char * str)
{
	static char hex[256];
	int i;
	hex[0] = '0';
	hex[1] = 'x';

	for(i=2, str++, str++; *str; str++)
	{
		if(*str != '"') hex[i++] = *str;
	}
	hex[i] = 0;
	return hex;
}

char * format_binary(char * str)
{
	static char bin[80];
	int value;
	int token_counter;

	for(value = 0, token_counter = 0; *str; str++)
	{
		if(*str != ' ') // ignore ' '
		{
			if(*str != '"')
			{
				value <<= 1;

				if(*str == '1') 
				{
					value |= 1;
				}
				else if(*str == '0')
				{
				}
				else return NULL; // not binary value
			}
			else
			{
				token_counter ++;
				if(token_counter >= 2) break;
			}
		}
	}

	sprintf(bin, "%d", value);
	return bin;
}

char * format_value(char * str)
{
	static char value[1024];
	char * ret;
	int i, j, len;
	int filter;

	// remove the leading ' ' and ending ';'
	// also remove any comment
	for(i = 0, filter = 1; *str; str++)
	{
		if(filter) 
		{
			if(*str == '-' && *(str+1) == '-') break; // meet the comment
			if(*str != ';' && *str != ' ') value[i++] = *str;
		}
		else value[i++] = *str;

		if(*str == '"') filter = !filter;
	}
	value[i] = 0; 
	len = i;

	if((value[0] == 'x' || value[0] == 'X') && value[1] == '"') // it is a hex number
	{
		return format_hex(value);
	}

	if(value[0] == '"') 
	{
		ret = format_binary(value);
		if(ret == NULL) return value; // it is a string
		else return ret; // it is a binary number
	}

	// replace '2**'
	for(i = 0; i < len - 3; i++)
	{
		if(value[i] == '2')
		{
			for(j = i+1; j < len - 2; j++)
			{
				if(value[j] == ' ') continue;
				if(value[j] == '*')
				{
					if(value[j+1] == '*')
					{
						value[j] = '<';
						value[j+1] = '<';
						value[i] = '1';
					}
					else break;
				}
				else break;
			}
		}
	}
	
	// if there is +, -, *, /, <, > in it, add brackets
	int search = 1;
	for( i=0; i<len && search; i++)
	{
		switch(value[i])
		{
		case '+':
		case '-':
		case '*':
		case '/':
		case '<':
		case '>':
			for(int j=len-1; j>=0; j--)
			{
				value[j+1] = value[j];
			}
			value[0] = '(';
			value[len+1] = ')';
			value[len+2] = 0;
			len += 2;
			search = 0;
			break;
		}
	}

	return value; // other value, e.g. boolean
}

void abstract(FILE *hdl_fp, FILE *header_fp)
{
#define BUFFER_LEN 1024
	int state, next_state;
	int input;
	char name_string[BUFFER_LEN];
	char value_string[BUFFER_LEN];
	char * input_buffer;
	int ignore_space;
	
	next_state = ST_SEARCHING;
	input_buffer = name_string;
	ignore_space = 0;

	while(!feof(hdl_fp))
	{
		state = next_state;

		switch(state)
		{
		case ST_SEARCHING:
			ignore_space = 0;
			break;
		case ST_GET_NAME:
			ignore_space = 0;
			break;
		case ST_FIND_VALUE:
			ignore_space = 0;
			break;
		case ST_GET_VALUE:
			ignore_space = 1;
			break;
		default:
			ignore_space = 0;
			break;
		}
		
		// get the input
		if(ignore_space) // read the space as well
		{
			int scan_pt = 0;
			int filter = 1;
			while(scan_pt < BUFFER_LEN-1)
			{
				int ch = fgetc(hdl_fp);
				
				if(ch == EOF) 
				{
					input_buffer[scan_pt] = 0;
					break;
				}

				if(ch == '"') filter = ! filter;

				if(filter)
				{
					if(ch < 32) continue; // ignore non-display char
					if(ch == ')') 
					{
						input_buffer[scan_pt] = 0;
						break; // end of the HDL line
					}
					if(ch == ';') 
					{
						input_buffer[scan_pt] = 0;
						break; // end of the HDL line
					}
				}

				input_buffer[scan_pt++] = ch;
			}
		}
		else
			fscanf(hdl_fp, "%s", input_buffer);

		if(stricmp(input_buffer, "constant") == 0)
			input = MARK_VHDL_CONST;
		else if(stricmp(input_buffer, ":=") == 0)
			input = MARK_VHDL_ASSIGN;
		else if(strstr(input_buffer, ";") || strstr(input_buffer, ")") )
		{
			if (state != ST_FIND_VALUE)
			{
				input = MARK_VHDL_ENDTOKEN;
			}
			else
			{
				input = MARK_DONTCARE;
			}
		}
		else 
			input = MARK_DONTCARE;

		if (input_buffer[0] != 0 && input_buffer[1] != 0) // make sure there are enough charaters in the buffer
		{
			if(input_buffer[0] == '-' && input_buffer[1] == '-') 
			{
				if (input_buffer[2] == '%') // pass on this line
				{
					fprintf(header_fp, "%s ", input_buffer + 3);
					fgets(input_buffer, 1024, hdl_fp);
					fprintf(header_fp, "%s", input_buffer);
				}
				else // skip this line
				{
					fgets(input_buffer, 1024, hdl_fp);
					continue;
				}
			}
		}

		// the state machine
		switch(state)
		{
		case ST_SEARCHING:
			if(input == MARK_VHDL_CONST) next_state = ST_GET_NAME;
			break;
		case ST_GET_NAME:
			next_state = ST_FIND_VALUE;
			input_buffer = value_string; // scan the input buffer into the value buffer
			break;
		case ST_FIND_VALUE:
			if(input == MARK_VHDL_ASSIGN) next_state = ST_GET_VALUE;
			else if(input == MARK_VHDL_ENDTOKEN) // no value assigned to the constant
			{
				input_buffer = name_string;
				next_state = ST_SEARCHING;
			}
			break;
		case ST_GET_VALUE:
			fprintf(header_fp, "#define \t %s \t %s\n", name_string, format_value(value_string));
			next_state = ST_SEARCHING;
			input_buffer = name_string;
			break;
		default:
			next_state = state;
		}

	}
}

char * get_currentpath(void)
{
	return ".";
}

int is_directory(char * path)
{
    DWORD dw =  GetFileAttributes(path);
    return ( dw != 0xffffffff  &&  dw & FILE_ATTRIBUTE_DIRECTORY);
}

int get_path(char * str, char * path)
{
	int i;
	int len;
	if(is_directory(str))
	{
		// copy the path
		for(i = 0; str[i]; i++) path[i] = str[i];
		
		// remove the end token if there is any
		if(path[i-1] == FOLDER_TOKEN) 
		{
			len =  i-1;
		} 
		else len =  i;

		path[len] = 0;

	}
	else
	{
		// find the token
		for(i = strlen(str); i >= 0; i--) 
		{
			if(str[i] == FOLDER_TOKEN) break;
		}

		// copy the reset
		path[i] = 0; len = i;
		for(i--; i >=0; i--) path[i] = str[i];
	}

	return len;
}

char * next_file(char * src)
{
	static int first = 1;
	char from[1024];
	static WIN32_FIND_DATA FindFileData;
	static HANDLE hFind;
	static char fullname[1024];
	int path_len;

	if(is_directory(src)) // a directory
	{
		if(src[strlen(src) - 1] == '\\')
		{
			sprintf(from, "%s*.vhd", src);
		}
		else
		{
			sprintf(from, "%s%c*.vhd", src, FOLDER_TOKEN);
		}
	}
	else
	{
		sprintf(from, "%s", src);
	}

	if(first)
	{
		first = 0;
		hFind = FindFirstFile(from, &FindFileData);
		if (hFind == INVALID_HANDLE_VALUE) 
		{
			printf ("File searching failed (%s)\n", from);
			return NULL;
		} 
		else 
		{
			if(FindFileData.cFileName[strlen(FindFileData.cFileName) - 1] == '~')
				return next_file(src);

			path_len = get_path(src, fullname);
			sprintf(fullname + path_len, "%c%s", FOLDER_TOKEN, FindFileData.cFileName);
			return fullname;
		}
	}
	else
	{
		if(!FindNextFile(hFind, &FindFileData))
		{
			FindClose(hFind);
			return NULL;
		}
		else 
		{
			if(FindFileData.cFileName[strlen(FindFileData.cFileName) - 1] == '~')
				return next_file(src);

			path_len = get_path(src, fullname);
			sprintf(fullname + path_len, "%c%s", FOLDER_TOKEN, FindFileData.cFileName);
			return fullname;
		}
	}
}

char * get_targetpath(char * name, char * path)
{
	static char filename[1024];

	int i, offset;

	if(!is_directory(path)) return path; // path is a file name already

	for(offset=0; path[offset]; offset++)
	{
		filename[offset] = path[offset];
	}
	
	if(filename[offset-1] != '\\')
	{
		filename[offset++] = '\\';
	}

	for(i = strlen(name); i>=0; i--)
	{
		if(name[i] == '\\') break; // find the position of the pure name
	}
	for(i++; name[i] != 0 && name[i] != '.'; i++, offset++)
	{
		filename[offset] = name[i];
	}
	filename[offset++] = '.';
	filename[offset++] = 'h';
	filename[offset++] = 0;
	
	return filename;
}

int convert_single(char * from, char * to)
{
	static int first = 1;

	FILE *hdl_fp;
	FILE *header_fp;

	if(first)
	{
		first = 0;
		remove(to);
	}
	else
	{
		if(!single_file) remove(to);
	}

	hdl_fp = fopen(from, "rt");
	if(hdl_fp == NULL)
	{
		printf("Can not open the HDL file: %s\n", from);
		return 1;
	}

	header_fp = fopen(to, "a+t");
	if(header_fp == NULL)
	{
		printf("Can not creat the C header file: %s\n", to);
		return 1;
	}

	printf("Convert %s to %s ...\n", from, to);

	fprintf(header_fp, "// Converted from %s\n", from);
	abstract(hdl_fp, header_fp);

	fclose(hdl_fp);
	fclose(header_fp);

	return 0;
}

int convert(char * from, char * to)
{
	char * from_file;
	char * to_file;

	while(from_file = next_file(from))
	{
		if(single_file) to_file = to;
		else to_file = get_targetpath(from_file, to);
		if(convert_single(from_file, to_file)) return 1;
	}
	return 0;
}

int main(int argc, char* argv[])
{
	char * source_path;
	char * target_path;
	
	single_file = 0;

	printf("VHDL constant to C header v0.4\n");

	switch(argc) 
	{
	case 1: // convert all the files under current directory
		source_path = get_currentpath();
		target_path = source_path;
		return convert(source_path, target_path);
	case 2: // convert from another directory
		source_path = argv[1];
		if(!is_directory(source_path))
		{
			printf("Path is not a directory !!!\n");
			return -1;
		}
		target_path = get_currentpath();
		return convert(source_path, target_path);
	case 3: // convert from one directory to another or one file to another
		source_path = argv[1];
		target_path = argv[2];
		if(!is_directory(target_path)) single_file = 1;
		return convert(source_path, target_path);

	default:
		printf("Too many parameters !!!\n");
		return 1;
	}

	return -1;
}

// EOF

⌨️ 快捷键说明

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