📄 vheader.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 + -