parser for gds started

This commit is contained in:
Mario Hüttel 2018-05-07 13:27:50 +02:00
commit db753126ac
5 changed files with 370 additions and 0 deletions

74
.gitignore vendored Normal file
View File

@ -0,0 +1,74 @@
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
*.user

4
CMakeLists.txt Normal file
View File

@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 2.8)
project(gds-render)
add_executable(${PROJECT_NAME} "main.c" "gdsparse.c")

219
gdsparse.c Normal file
View File

@ -0,0 +1,219 @@
#include "gdsparse.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define GDS_ERROR(fmt, ...) printf("[PARSE_ERROR] " fmt "\n", #__VA_ARGS__)
#define GDS_WARN(fmt, ...) printf("[PARSE_WARNING] " fmt "\n", #__VA_ARGS__)
enum parsing_state {PARSING_LENGTH = 0, PARSING_TYPE, PARSING_DAT};
enum record {
HEADER = 0x0002,
BGNLIB = 0x0102,
LIBNAME = 0x0206,
UNITS = 0x0305,
ENDLIB = 0x0400,
BGNSTR = 0x0500,
STRNAME = 0x0606,
ENDSTR = 0x0700,
};
static struct gds_library * append_library(struct gds_library *curr_arr, unsigned int curr_count)
{
unsigned int size = (curr_count +1) * sizeof(struct gds_library);
return (struct gds_library *)realloc(curr_arr, size);
}
static struct gds_cell * append_cell(struct gds_cell *curr_arr, unsigned int curr_count)
{
unsigned int size = (curr_count +1) * sizeof(struct gds_cell);
return (struct gds_cell *)realloc(curr_arr, size);
}
static int name_library(struct gds_library *current_library, unsigned int bytes, char* data) {
int len;
data[bytes] = 0; // Append '0'
len = strlen(data);
if (len > CELL_NAME_MAX-1) {
GDS_ERROR("Library name '%s' too long: %d\n", data, len);
return -1;
} else {
strcpy(current_library->name, data);
printf("Named library: %s\n", current_library->name);
}
return 0;
}
static int name_cell(struct gds_cell *cell, unsigned int bytes, char* data) {
int len;
data[bytes] = 0; // Append '0'
len = strlen(data);
if (len > CELL_NAME_MAX-1) {
GDS_ERROR("Library name '%s' too long: %d\n", data, len);
return -1;
} else {
strcpy(cell->name, data);
printf("Named library: %s\n", cell->name);
}
return 0;
}
int parse_gds_from_file(const char *filename, struct gds_library **library_array, unsigned int *count)
{
char workbuff[1024];
int read;
int run = 1;
FILE *gds_file = NULL;
uint16_t rec_data_length;
enum record rec_type;
enum parsing_state state = PARSING_LENGTH;
struct gds_library *current_lib = NULL;
struct gds_cell *current_cell = NULL;
struct gds_graphics *current_graphics = NULL;
struct gds_cell_instance *current_s_reference = NULL;
////////////
struct gds_library *lib_arr = NULL;
struct gds_cell *cell_arr = NULL;
unsigned int lib_arr_cnt = 0;
unsigned int cell_arr_cnt = 0;
/* open File */
gds_file = fopen(filename, "r");
if (gds_file == NULL) {
GDS_ERROR("Could not open File %s", filename);
return -1;
}
/* Record parser */
while (run == 1) {
switch (state) {
case PARSING_LENGTH:
read = fread(workbuff, sizeof(char), 2, gds_file);
if (read != 2 && (current_cell != NULL ||
current_graphics != NULL ||
current_lib != NULL ||
current_s_reference != NULL)) {
GDS_ERROR("End of File. with openend structs/libs");
run = -2;
break;
} else if (read != 2) {
/* EOF */
run = 0;
break;
}
rec_data_length = (uint16_t)((((uint16_t)(workbuff[0])) << 8) |
(uint16_t)(workbuff[1]));
if (rec_data_length < 4) {
/* Possible Zero-Padding: */
run = 0;
GDS_WARN("Zero Padding detected!");
if (current_cell != NULL ||
current_graphics != NULL ||
current_lib != NULL ||
current_s_reference != NULL) {
GDS_ERROR("Not all structures closed");
run = -2;
}
break;
}
rec_data_length -= 4;
state = PARSING_TYPE;
break;
case PARSING_TYPE:
read = fread(workbuff, sizeof(char), 2, gds_file);
if (read != 2) {
run = -2;
GDS_ERROR("Unexpected end of file");
break;
}
rec_type = (uint16_t)((((uint16_t)(workbuff[0])) << 8) |
(uint16_t)(workbuff[1]));
state = PARSING_DAT;
/* if begin: Allocate structures */
switch (rec_type) {
case BGNLIB:
lib_arr = append_library(lib_arr, lib_arr_cnt);
lib_arr_cnt++;
if (lib_arr == NULL) {
GDS_ERROR("Allocating memory failed");
run = -3;
break;
}
printf("Entering Lib\n");
current_lib = &(lib_arr[lib_arr_cnt-1]);
break;
case ENDLIB:
if (current_lib == NULL) {
run = -4;
GDS_ERROR("Closing Library with no opened library");
break;
}
current_lib = NULL;
printf("Leaving Library\n");
case BGNSTR:
cell_arr = append_cell(cell_arr, cell_arr_cnt);
cell_arr_cnt++;
if (lib_arr == NULL) {
GDS_ERROR("Allocating memory failed");
run = -3;
break;
}
printf("Entering Cell\n");
current_cell = &(cell_arr[cell_arr_cnt-1]);
break;
case ENDSTR:
if (current_cell == NULL) {
run = -4;
GDS_ERROR("Closing cell with no opened cell");
break;
}
current_cell = NULL;
printf("Leaving Cell\n");
break;
}
break;
case PARSING_DAT:
read = fread(workbuff, sizeof(char), rec_data_length, gds_file);
state = PARSING_LENGTH;
if (read != rec_data_length) {
GDS_ERROR("Could not read enough data");
run = -5;
break;
}
/* No Data -> No Processing */
if (!read) break;
switch (rec_type) {
case LIBNAME:
name_library(current_lib, read,workbuff);
break;
case STRNAME:
name_cell(current_cell, read, workbuff);
break;
}
break;
}
}
fclose(gds_file);
*library_array = lib_arr;
*count = lib_arr_cnt;
return run;
}

62
gdsparse.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef __GDSPARSE_H__
#define __GDSPARSE_H__
#include <stdint.h>
#define CELL_NAME_MAX (100)
enum graphics_type {GRAPHIC_PATH = 0, GRAPHIC_POLYGON = 1};
struct gds_time_field {
uint16_t year;
uint16_t month;
uint16_t day;
uint16_t hour;
uint16_t minute;
uint16_t second;
};
struct gds_point {
int x;
int y;
};
struct gds_graphics {
enum graphics_type type;
struct gds_point *vertices;
int vertices_count;
uint16_t layer;
uint16_t datatype;
};
struct gds_cell_instance {
char ref_name[CELL_NAME_MAX];
struct gds_cell *cell_ref;
struct gds_point origin;
int flipped;
double angle;
double magnification;
};
struct gds_cell {
char name[CELL_NAME_MAX];
struct gds_time_field mod_time;
struct gds_time_field access_time;
struct gds_cell_instance *child_cells;
int child_cells_count;
struct gds_graphics *graphic_objs;
int graphic_objs_count;
};
struct gds_library {
char name[CELL_NAME_MAX];
struct gds_time_field time;
double unit_to_meters;
struct gds_cell *cells;
int cells_count;
};
int parse_gds_from_file(const char *filename, struct gds_library **library_array, unsigned int *count);
#endif /* __GDSPARSE_H__ */

11
main.c Normal file
View File

@ -0,0 +1,11 @@
#include <stdio.h>
#include "gdsparse.h"
int main()
{
struct gds_library *libs;
unsigned int count = 0;
parse_gds_from_file("/home/mari/Desktop/test.gds", &libs, &count);
return 0;
}