Skip to content

Commit fdd14c2

Browse files
committed
Header include/spec.h deleted and its content moved to
the specification compiler template file.
1 parent 7d7564d commit fdd14c2

File tree

4 files changed

+63
-59
lines changed

4 files changed

+63
-59
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ release32 : CFLAGS += -mx32
2626
SRC = src/parser.c src/scanner.c src/utils.c src/converters.c \
2727
test/main.c test/scanner_test.c test/parser_test.c test/test_utils.c test/utils_test.c test/$(SPEC).c
2828

29-
HEADERS = include/fix.h include/spec.h include/$(SPEC).h src/fix_impl.h test/test_utils.h
29+
HEADERS = include/fix.h include/$(SPEC).h src/fix_impl.h test/test_utils.h
3030

3131
$(BIN) : $(SRC) $(HEADERS)
3232
$(CC) -o $@ $(CFLAGS) $(SRC)
3333

3434
# clean-up
3535
.PHONY : clean
3636
clean :
37-
rm -f include/$(SPEC).h src/$(SPEC).c $(BIN)
37+
rm -f include/$(SPEC).h test/$(SPEC).c $(BIN)
3838

doc/doc.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ FullFIX is a library for parsing Financial Information eXchange (FIX) messages.
66

77
* `include/`
88
* `fix.h` - main header file, contains all the data definitions and function declarations;
9-
* `spec.h` - some macro definitions to support the compiled specification, should not be used anywhere else.
109
* `src/`
1110
* `scanner.c` - parser, first pass;
1211
* `parser.c` - parser, second pass;
@@ -16,6 +15,7 @@ FullFIX is a library for parsing Financial Information eXchange (FIX) messages.
1615
* `test/`: unit tests
1716
* `tools/`
1817
* `compile-spec` - FIX specification compiler;
18+
* `spec.c.template` - template for specification compiler.
1919
* `perf-stat` - performance statistics collector.
2020
* `doc/`
2121
* `doc.md` - main documentation (this file);
@@ -50,7 +50,7 @@ The same functions can also act as format validators.
5050
The parser takes raw bytes as input and provides an API for extracting messages one-by-one.
5151
Each message gets extracted and parsed (steps 1 and 2 above) and returned to the user
5252
as an efficient `tag->value` mapping. All processing happens in the same thread of execution
53-
to avoid any synchronisation overhead, especially when integrating the library into
53+
to avoid any synchronisation overhead, especially when integrating the library into
5454
an existing software.
5555

5656
### Data representation

tools/compile-spec

Lines changed: 10 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3030

3131
from sys import exit, argv
3232
import xml.etree.ElementTree as ET
33-
from os.path import basename, splitext, exists, isdir, join as path_join
33+
from os.path import basename, splitext, exists, isdir, dirname, join as path_join
3434
from collections import namedtuple, OrderedDict, deque
3535
from functools import singledispatch
3636
from itertools import chain
@@ -64,6 +64,14 @@ def write_file(file_name, fmt, data):
6464
except IOError as e:
6565
die('Cannot write "{}": {}'.format(file_name, e))
6666

67+
# spec template
68+
def read_spec_template():
69+
try:
70+
with open(path_join(dirname(argv[0]), 'spec.c.template')) as f:
71+
return f.read()
72+
except IOError as e:
73+
die('Cannot read template file: ' + str(e))
74+
6775
# data extractors -------------------------------------------------------------------------------------
6876
# tag types
6977
RegularTag = namedtuple('RegularTag', ('value', 'data_type'))
@@ -474,45 +482,9 @@ def make_parser_table_body(messages):
474482

475483
return '\n'.join(s for s in iter_body())
476484

477-
# .c file format
478-
__c_fmt = \
479-
'''// AUTOMATICALLY GENERATED FILE - DO NOT EDIT!
480-
#include <{base_name}.h>
481-
#include <spec.h>
482-
483-
// empty group info function
484-
static
485-
const fix_group_info* empty_group_info_func(const unsigned tag __attribute__((__unused__)))
486-
{{
487-
return NULL;
488-
}}
489-
490-
// groups ----------------------------------------------------------------------------------------
491-
{groups}
492-
493-
{common}
494-
495-
// messages --------------------------------------------------------------------------------------
496-
{messages}
497-
498-
// parser table ----------------------------------------------------------------------------------
499-
static
500-
const fix_message_info* {prefix}_parser_table(const fix_string msg_type)
501-
{{
502-
const char* s = msg_type.begin;
503-
504-
{parser_table}
505-
}}
506-
507-
// parser constructor ----------------------------------------------------------------------------
508-
fix_parser* create_{prefix}_parser()
509-
{{
510-
return create_fix_parser({prefix}_parser_table, CONST_LIT("{fix_version}"));
511-
}}'''
512-
513485
# code generator
514486
def write_code(name, file_name_base, prefix, fix_version, groups, messages, common):
515-
write_file(name, __c_fmt, { \
487+
write_file(name, read_spec_template(), { \
516488
'base_name' : file_name_base, \
517489
'prefix' : prefix, \
518490
'fix_version' : fix_version, \

include/spec.h renamed to tools/spec.c.template

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
2626
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2727
*/
2828

29-
#pragma once
29+
// AUTOMATICALLY GENERATED FILE - DO NOT EDIT!
30+
31+
#include <{base_name}.h>
3032

3133
// macro to support compiled specification
3234
#define NONE ((unsigned)-1)
@@ -47,63 +49,93 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4749
// group --------------------------------------------------------------------------------------
4850
#define TAG_INFO_FUNC(name) \
4951
static unsigned name ## _tag_info_func(const unsigned tag) \
50-
{ \
52+
{{ \
5153
switch(tag) \
52-
{
54+
{{
5355

5456
#define END_TAG_INFO \
5557
default: return NONE; \
56-
} \
57-
}
58+
}} \
59+
}}
5860

5961
#define GROUP_INFO_FUNC(name) \
6062
static const fix_group_info* name ## _group_info_func(const unsigned tag) \
61-
{ \
63+
{{ \
6264
switch(tag) \
63-
{
65+
{{
6466

6567
#define GROUP_INFO(len_tag_name, group_name) \
6668
case len_tag_name: return &group_name ## _group_info;
6769

6870
#define END_GROUP_INFO \
6971
default: return NULL; \
70-
} \
71-
}
72+
}} \
73+
}}
7274

7375
#define GROUP_INFO_STRUCT(name, node_size, first_tag) \
7476
static const fix_group_info \
75-
name ## _group_info = { (node_size), (first_tag), name ## _tag_info_func, name ## _group_info_func };
77+
name ## _group_info = {{ (node_size), (first_tag), name ## _tag_info_func, name ## _group_info_func }};
7678

7779
#define EMPTY_GROUP_INFO(name, node_size, first_tag) \
7880
static const fix_group_info \
79-
name ## _group_info = { (node_size), (first_tag), name ## _tag_info_func, empty_group_info_func };
81+
name ## _group_info = {{ (node_size), (first_tag), name ## _tag_info_func, empty_group_info_func }};
8082

8183
// message ---------------------------------------------------------------------------------------
8284
#define MESSAGE_TAG_INFO_FUNC TAG_INFO_FUNC
8385

8486
#define END_MESSAGE_TAG_INFO \
8587
default: return common_tag_info_func(tag); \
86-
} \
87-
}
88+
}} \
89+
}}
8890

8991
#define MESSAGE_GROUP_INFO_FUNC GROUP_INFO_FUNC
9092

9193
#define END_MESSAGE_GROUP_INFO \
9294
default: return common_group_info_func(tag); \
93-
} \
94-
}
95+
}} \
96+
}}
9597

9698
#define MESSAGE_GROUP_INFO_STRUCT(name, node_size) \
9799
static const fix_message_info \
98-
name ## _message_info = { { (node_size), 0, name ## _tag_info_func, name ## _group_info_func }, name };
100+
name ## _message_info = {{ {{ (node_size), 0, name ## _tag_info_func, name ## _group_info_func }}, name }};
99101

100102
#define EMPTY_MESSAGE_GROUP_INFO(name, node_size) \
101103
static const fix_message_info \
102-
name ## _message_info = { { (node_size), 0, name ## _tag_info_func, common_group_info_func }, name };
104+
name ## _message_info = {{ {{ (node_size), 0, name ## _tag_info_func, common_group_info_func }}, name }};
103105

104106
// parser table ----------------------------------------------------------------------------------
105107
#define RETURN_MESSAGE(name) \
106108
return &name ## _message_info
107109

108110
#define RETURN_MESSAGE_OR_NULL(name) \
109111
return *s == SOH ? &name ## _message_info : NULL
112+
113+
// empty group info function --------------------------------------------------------------------
114+
static
115+
const fix_group_info* empty_group_info_func(const unsigned tag __attribute__((__unused__)))
116+
{{
117+
return NULL;
118+
}}
119+
120+
// groups ----------------------------------------------------------------------------------------
121+
{groups}
122+
123+
{common}
124+
125+
// messages --------------------------------------------------------------------------------------
126+
{messages}
127+
128+
// parser table ----------------------------------------------------------------------------------
129+
static
130+
const fix_message_info* {prefix}_parser_table(const fix_string msg_type)
131+
{{
132+
const char* s = msg_type.begin;
133+
134+
{parser_table}
135+
}}
136+
137+
// parser constructor ----------------------------------------------------------------------------
138+
fix_parser* create_{prefix}_parser()
139+
{{
140+
return create_fix_parser({prefix}_parser_table, CONST_LIT("{fix_version}"));
141+
}}

0 commit comments

Comments
 (0)