зеркало из https://github.com/mozilla/gecko-dev.git
Fixed usage-string typo.
Update to 0.5.7 IDL_tree_property_get API. Reworked input callback for cleanliness. Add (not-yet-working) infrastructure for %{ C %} raw blocks.
This commit is contained in:
Родитель
8716e7650b
Коммит
b7e56cfb2f
|
@ -33,7 +33,7 @@ gboolean generate_nothing = FALSE;
|
||||||
static char xpidl_usage_str[] =
|
static char xpidl_usage_str[] =
|
||||||
"Usage: %s [-i] [-d] [-h] [-w] [-v] [-I path] [-n] filename.idl\n"
|
"Usage: %s [-i] [-d] [-h] [-w] [-v] [-I path] [-n] filename.idl\n"
|
||||||
" -i generate InterfaceInfo data (filename.int) (NYI)\n"
|
" -i generate InterfaceInfo data (filename.int) (NYI)\n"
|
||||||
" -d generate HTML documenation (filename.html) (NYI)\n"
|
" -d generate HTML documentation (filename.html) (NYI)\n"
|
||||||
" -h generate C++ headers (filename.h)\n"
|
" -h generate C++ headers (filename.h)\n"
|
||||||
" -w turn on warnings (recommended)\n"
|
" -w turn on warnings (recommended)\n"
|
||||||
" -v verbose mode (NYI)\n"
|
" -v verbose mode (NYI)\n"
|
||||||
|
|
|
@ -93,7 +93,7 @@ interface(TreeState *state)
|
||||||
|
|
||||||
fprintf(state->file, "/* starting interface %s */\n",
|
fprintf(state->file, "/* starting interface %s */\n",
|
||||||
className);
|
className);
|
||||||
iid = IDL_interface_get_property(iface, "uuid");
|
iid = IDL_tree_property_get(iface, "uuid");
|
||||||
if (iid) {
|
if (iid) {
|
||||||
char *iidName, *iidStruct;
|
char *iidName, *iidStruct;
|
||||||
/* XXX use nsID parsing routines to validate? */
|
/* XXX use nsID parsing routines to validate? */
|
||||||
|
|
|
@ -112,16 +112,27 @@ msg_callback(int level, int num, int line, const char *file,
|
||||||
#define INPUT_BUF_CHUNK 8192
|
#define INPUT_BUF_CHUNK 8192
|
||||||
|
|
||||||
struct input_callback_data {
|
struct input_callback_data {
|
||||||
FILE *input;
|
FILE *input; /* stream for getting data */
|
||||||
char *filename;
|
char *filename; /* where did I come from? */
|
||||||
int lineno;
|
int lineno; /* last lineno processed */
|
||||||
char *buf;
|
char *buf; /* buffer for data */
|
||||||
char *point;
|
char *point; /* next char to feed to libIDL */
|
||||||
int len;
|
int len; /* amount of data read into the buffer */
|
||||||
int max;
|
int max; /* size of the buffer */
|
||||||
struct input_callback_data *next;
|
struct input_callback_data *next; /* file from which we were included */
|
||||||
|
char f_raw : 2, /* in a raw block when starting next block */
|
||||||
|
f_comment : 2, /* in a comment when starting next block */
|
||||||
|
f_include : 2; /* in an #include when starting next block */
|
||||||
|
char last_read[2]; /* last 1/2 chars read, for spanning blocks */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* values for f_{raw,comment,include} */
|
||||||
|
#define INPUT_IN_NONE 0x0
|
||||||
|
#define INPUT_IN_FULL 0x1 /* we've already started one */
|
||||||
|
#define INPUT_IN_START 0x2 /* we're about to start one */
|
||||||
|
#define INPUT_IN_PART 0x3 /* we might be about to start one (check
|
||||||
|
last_read to be sure) */
|
||||||
|
|
||||||
struct input_callback_stack {
|
struct input_callback_stack {
|
||||||
struct input_callback_data *top;
|
struct input_callback_data *top;
|
||||||
GHashTable *includes;
|
GHashTable *includes;
|
||||||
|
@ -138,7 +149,7 @@ fopen_from_includes(const char *filename, const char *mode,
|
||||||
filebuf = g_strdup_printf("%s/%s", include_path->directory, filename);
|
filebuf = g_strdup_printf("%s/%s", include_path->directory, filename);
|
||||||
if (!filebuf)
|
if (!filebuf)
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifdef DEBUG_shaver
|
#ifdef DEBUG_shaver_bufmgmt
|
||||||
fprintf(stderr, "looking for %s as %s\n", filename, filebuf);
|
fprintf(stderr, "looking for %s as %s\n", filename, filebuf);
|
||||||
#endif
|
#endif
|
||||||
file = fopen(filebuf, mode);
|
file = fopen(filebuf, mode);
|
||||||
|
@ -150,13 +161,13 @@ fopen_from_includes(const char *filename, const char *mode,
|
||||||
static struct input_callback_data *
|
static struct input_callback_data *
|
||||||
new_input_callback_data(const char *filename, IncludePathEntry *include_path)
|
new_input_callback_data(const char *filename, IncludePathEntry *include_path)
|
||||||
{
|
{
|
||||||
struct input_callback_data *new_data = malloc(sizeof *new_data);
|
struct input_callback_data *new_data = calloc(1, sizeof *new_data);
|
||||||
if (!new_data)
|
if (!new_data)
|
||||||
return NULL;
|
return NULL;
|
||||||
new_data->input = fopen_from_includes(filename, "r", include_path);
|
new_data->input = fopen_from_includes(filename, "r", include_path);
|
||||||
if (!new_data->input)
|
if (!new_data->input)
|
||||||
return NULL;
|
return NULL;
|
||||||
new_data->buf = malloc(INPUT_BUF_CHUNK);
|
new_data->buf = malloc(INPUT_BUF_CHUNK + 1); /* trailing NUL */
|
||||||
if (!new_data->buf) {
|
if (!new_data->buf) {
|
||||||
fclose(new_data->input);
|
fclose(new_data->input);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -182,7 +193,8 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
|
||||||
struct input_callback_stack *stack = user_data;
|
struct input_callback_stack *stack = user_data;
|
||||||
struct input_callback_data *data = stack->top, *new_data = NULL;
|
struct input_callback_data *data = stack->top, *new_data = NULL;
|
||||||
int rv, avail, copy;
|
int rv, avail, copy;
|
||||||
char *include_start, *ptr;
|
char *search, *check_point, *ptr, *end_copy, *raw_start, *comment_start,
|
||||||
|
*include_start;
|
||||||
|
|
||||||
switch(reason) {
|
switch(reason) {
|
||||||
case IDL_INPUT_REASON_INIT:
|
case IDL_INPUT_REASON_INIT:
|
||||||
|
@ -203,7 +215,6 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
|
||||||
assert(avail >= 0);
|
assert(avail >= 0);
|
||||||
|
|
||||||
if (!avail) {
|
if (!avail) {
|
||||||
char *comment_start = NULL, *include_start = NULL, *ptr;
|
|
||||||
data->point = data->buf;
|
data->point = data->buf;
|
||||||
|
|
||||||
/* fill the buffer */
|
/* fill the buffer */
|
||||||
|
@ -222,78 +233,94 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
|
||||||
stack->top = data;
|
stack->top = data;
|
||||||
IDL_file_set(data->filename, ++data->lineno);
|
IDL_file_set(data->filename, ++data->lineno);
|
||||||
IDL_inhibit_pop();
|
IDL_inhibit_pop();
|
||||||
|
data->f_include = INPUT_IN_NONE;
|
||||||
goto fill_start;
|
goto fill_start;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
data->buf[data->len] = 0;
|
||||||
/*
|
|
||||||
* strip comments
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX
|
|
||||||
* What if the last char in this block is '/' and the first in the
|
|
||||||
* next block is '*'? I'm not sure it matters, because I don't
|
|
||||||
* think there are any legal IDL syntaxes with '/' in them.
|
|
||||||
*
|
|
||||||
* XXX what about "/* " appearing in the IDL?
|
|
||||||
*/
|
|
||||||
if (!comment_start)
|
|
||||||
comment_start = strstr(data->buf, "/*");
|
|
||||||
while (comment_start) {
|
|
||||||
char *end = strstr(comment_start, "*/");
|
|
||||||
int comment_length;
|
|
||||||
int bytes_after_comment;
|
|
||||||
|
|
||||||
if (!end)
|
|
||||||
goto fill_buffer;
|
|
||||||
|
|
||||||
end += 2; /* star-slash */
|
|
||||||
comment_length = end - comment_start;
|
|
||||||
bytes_after_comment = data->buf + data->len - end;
|
|
||||||
|
|
||||||
/* found the end, move data around */
|
|
||||||
#ifdef DEBUG_shaver_bufmgmt
|
|
||||||
fprintf(stderr,
|
|
||||||
"FOUND COMMENT: (%d) %.*s, moving %d back\n",
|
|
||||||
comment_length, comment_length,
|
|
||||||
comment_start, bytes_after_comment);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memmove(comment_start, end, bytes_after_comment);
|
|
||||||
comment_start[bytes_after_comment] = '\0';
|
|
||||||
data->len -= comment_length;
|
|
||||||
|
|
||||||
#ifdef DEBUG_shaver_bufmgmt
|
|
||||||
fprintf(stderr, "new buffer:\n---\n%.*s\n---\n",
|
|
||||||
data->len, data->buf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* look for the next comment */
|
|
||||||
comment_start = strstr(data->buf, "/*");
|
|
||||||
|
|
||||||
} /* while(comment_start) */
|
|
||||||
|
|
||||||
/* we set avail here, because data->len is changed above */
|
|
||||||
|
|
||||||
avail = data->buf + data->len - data->point;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_point = data->point;
|
||||||
|
end_copy = data->buf + data->len;
|
||||||
/*
|
/*
|
||||||
* process includes
|
* When we're stripping comments and processing #includes,
|
||||||
|
* we need to be sure that we don't process anything inside
|
||||||
|
* \n%{ and \n%}. In order to simplify things, we only process
|
||||||
|
* comment, include or raw-block stuff when they're at the
|
||||||
|
* beginning of the block we're about to send (data->point).
|
||||||
|
* This makes the processing much simpler, since we can skip
|
||||||
|
* data->point ahead for comments and #include, and skip
|
||||||
|
* check_point ahead for raw blocks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
if (!(data->f_raw || data->f_comment || data->f_include)) {
|
||||||
* we only do #include magic at the beginning of the buffer.
|
/* look for first raw/comment/include */
|
||||||
* otherwise, we just set avail to cap the amount of data sent
|
|
||||||
* on this pass.
|
/* raw block */
|
||||||
*/
|
if ((raw_start = strstr(check_point, "\n%{"))) {
|
||||||
include_start = strstr(data->point, "#include \"");
|
end_copy = raw_start;
|
||||||
if (include_start == data->point) {
|
}
|
||||||
/* time to process the #include */
|
|
||||||
|
/* comment */
|
||||||
|
if ((comment_start = strstr(check_point, "/*")) &&
|
||||||
|
(!raw_start || comment_start < raw_start)) {
|
||||||
|
end_copy = comment_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* include */
|
||||||
|
if ((include_start = strstr(check_point, "#include")) &&
|
||||||
|
(!raw_start || include_start < raw_start) &&
|
||||||
|
(!comment_start || include_start < comment_start)) {
|
||||||
|
end_copy = include_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end_copy == raw_start)
|
||||||
|
data->f_raw = INPUT_IN_START;
|
||||||
|
|
||||||
|
else if (end_copy == comment_start)
|
||||||
|
data->f_comment = INPUT_IN_START;
|
||||||
|
|
||||||
|
else if (end_copy == include_start)
|
||||||
|
data->f_include = INPUT_IN_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((end_copy == data->buf || /* just found one at the start */
|
||||||
|
end_copy == data->buf + data->len /* left over */) &&
|
||||||
|
(data->f_raw || data->f_comment || data->f_include)) {
|
||||||
|
|
||||||
|
if (data->f_raw) {
|
||||||
|
ptr = strstr(check_point, "\n%}");
|
||||||
|
if (ptr) {
|
||||||
|
data->f_raw = INPUT_IN_NONE;
|
||||||
|
end_copy = ptr + 3;
|
||||||
|
#ifdef DEBUG_shaver_bufmgmt
|
||||||
|
fprintf(stderr, "RAW->%.*s<-RAW\n", end_copy - data->point,
|
||||||
|
data->point);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
assert(!data->f_comment && !data->f_include);
|
||||||
|
} else if (data->f_comment) {
|
||||||
|
/* XXX process doc comment */
|
||||||
|
ptr = strstr(check_point, "*/");
|
||||||
|
if (ptr) {
|
||||||
|
data->point = ptr + 2; /* star-slash */
|
||||||
|
#ifdef DEBUG_shaver_bufmgmt
|
||||||
|
fprintf(stderr, "COMMENT->%.*s<-COMMENT\n",
|
||||||
|
data->point - check_point, check_point);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
assert(!data->f_raw && !data->f_include);
|
||||||
|
} else if (data->f_include) {
|
||||||
|
/* process include */
|
||||||
const char *scratch;
|
const char *scratch;
|
||||||
char *filename = include_start + 10;
|
char *filename;
|
||||||
|
include_start = data->buf;
|
||||||
|
|
||||||
|
assert(!strncmp(include_start, "#include \"", 10));
|
||||||
|
filename = include_start + 10; /* skip #include " */
|
||||||
|
|
||||||
|
assert(filename < data->buf + data->len);
|
||||||
ptr = strchr(filename, '\"');
|
ptr = strchr(filename, '\"');
|
||||||
if (!ptr) {
|
if (!ptr) {
|
||||||
/* XXX report error */
|
/* XXX report error */
|
||||||
|
@ -303,12 +330,12 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
|
||||||
|
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
ptr = strrchr(filename, '.');
|
ptr = strrchr(filename, '.');
|
||||||
/* XXX is this a safe optimization? */
|
|
||||||
|
#ifdef DEBUG_shaver_bufmgmt
|
||||||
|
fprintf(stderr, "found #include %s\n", filename);
|
||||||
|
#endif
|
||||||
if (!g_hash_table_lookup(stack->includes, filename)) {
|
if (!g_hash_table_lookup(stack->includes, filename)) {
|
||||||
char *basename = filename;
|
char *basename = filename;
|
||||||
#ifdef DEBUG_shaver_includes
|
|
||||||
fprintf(stderr, "processing #include %s\n", filename);
|
|
||||||
#endif
|
|
||||||
filename = strdup(filename);
|
filename = strdup(filename);
|
||||||
ptr = strrchr(basename, '.');
|
ptr = strrchr(basename, '.');
|
||||||
if (ptr)
|
if (ptr)
|
||||||
|
@ -326,20 +353,16 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
|
||||||
IDL_file_get(&scratch, &data->lineno);
|
IDL_file_get(&scratch, &data->lineno);
|
||||||
data = stack->top = new_data;
|
data = stack->top = new_data;
|
||||||
IDL_file_set(data->filename, data->lineno);
|
IDL_file_set(data->filename, data->lineno);
|
||||||
|
#ifdef DEBUG_shaver_bufmgmt
|
||||||
|
fprintf(stderr, "processing #include %s\n", filename);
|
||||||
|
#endif
|
||||||
/* now continue getting data from new file */
|
/* now continue getting data from new file */
|
||||||
goto fill_start;
|
goto fill_start;
|
||||||
} else {
|
|
||||||
#ifdef DEBUG_shaver_includes
|
|
||||||
fprintf(stderr, "not processing #include %s again\n",
|
|
||||||
filename);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} else if (include_start) {
|
|
||||||
#ifdef DEBUG_shaver_includes
|
|
||||||
fprintf(stderr, "not processing #include yet\n");
|
|
||||||
#endif
|
|
||||||
avail = include_start - data->point;
|
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
|
||||||
|
avail = MIN(data->buf + data->len, end_copy) - data->point;
|
||||||
copy = MIN(avail, cb_data->fill.max_size);
|
copy = MIN(avail, cb_data->fill.max_size);
|
||||||
memcpy(cb_data->fill.buffer, data->point, copy);
|
memcpy(cb_data->fill.buffer, data->point, copy);
|
||||||
data->point += copy;
|
data->point += copy;
|
||||||
|
|
|
@ -33,7 +33,7 @@ gboolean generate_nothing = FALSE;
|
||||||
static char xpidl_usage_str[] =
|
static char xpidl_usage_str[] =
|
||||||
"Usage: %s [-i] [-d] [-h] [-w] [-v] [-I path] [-n] filename.idl\n"
|
"Usage: %s [-i] [-d] [-h] [-w] [-v] [-I path] [-n] filename.idl\n"
|
||||||
" -i generate InterfaceInfo data (filename.int) (NYI)\n"
|
" -i generate InterfaceInfo data (filename.int) (NYI)\n"
|
||||||
" -d generate HTML documenation (filename.html) (NYI)\n"
|
" -d generate HTML documentation (filename.html) (NYI)\n"
|
||||||
" -h generate C++ headers (filename.h)\n"
|
" -h generate C++ headers (filename.h)\n"
|
||||||
" -w turn on warnings (recommended)\n"
|
" -w turn on warnings (recommended)\n"
|
||||||
" -v verbose mode (NYI)\n"
|
" -v verbose mode (NYI)\n"
|
||||||
|
|
|
@ -93,7 +93,7 @@ interface(TreeState *state)
|
||||||
|
|
||||||
fprintf(state->file, "/* starting interface %s */\n",
|
fprintf(state->file, "/* starting interface %s */\n",
|
||||||
className);
|
className);
|
||||||
iid = IDL_interface_get_property(iface, "uuid");
|
iid = IDL_tree_property_get(iface, "uuid");
|
||||||
if (iid) {
|
if (iid) {
|
||||||
char *iidName, *iidStruct;
|
char *iidName, *iidStruct;
|
||||||
/* XXX use nsID parsing routines to validate? */
|
/* XXX use nsID parsing routines to validate? */
|
||||||
|
|
|
@ -112,16 +112,27 @@ msg_callback(int level, int num, int line, const char *file,
|
||||||
#define INPUT_BUF_CHUNK 8192
|
#define INPUT_BUF_CHUNK 8192
|
||||||
|
|
||||||
struct input_callback_data {
|
struct input_callback_data {
|
||||||
FILE *input;
|
FILE *input; /* stream for getting data */
|
||||||
char *filename;
|
char *filename; /* where did I come from? */
|
||||||
int lineno;
|
int lineno; /* last lineno processed */
|
||||||
char *buf;
|
char *buf; /* buffer for data */
|
||||||
char *point;
|
char *point; /* next char to feed to libIDL */
|
||||||
int len;
|
int len; /* amount of data read into the buffer */
|
||||||
int max;
|
int max; /* size of the buffer */
|
||||||
struct input_callback_data *next;
|
struct input_callback_data *next; /* file from which we were included */
|
||||||
|
char f_raw : 2, /* in a raw block when starting next block */
|
||||||
|
f_comment : 2, /* in a comment when starting next block */
|
||||||
|
f_include : 2; /* in an #include when starting next block */
|
||||||
|
char last_read[2]; /* last 1/2 chars read, for spanning blocks */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* values for f_{raw,comment,include} */
|
||||||
|
#define INPUT_IN_NONE 0x0
|
||||||
|
#define INPUT_IN_FULL 0x1 /* we've already started one */
|
||||||
|
#define INPUT_IN_START 0x2 /* we're about to start one */
|
||||||
|
#define INPUT_IN_PART 0x3 /* we might be about to start one (check
|
||||||
|
last_read to be sure) */
|
||||||
|
|
||||||
struct input_callback_stack {
|
struct input_callback_stack {
|
||||||
struct input_callback_data *top;
|
struct input_callback_data *top;
|
||||||
GHashTable *includes;
|
GHashTable *includes;
|
||||||
|
@ -138,7 +149,7 @@ fopen_from_includes(const char *filename, const char *mode,
|
||||||
filebuf = g_strdup_printf("%s/%s", include_path->directory, filename);
|
filebuf = g_strdup_printf("%s/%s", include_path->directory, filename);
|
||||||
if (!filebuf)
|
if (!filebuf)
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifdef DEBUG_shaver
|
#ifdef DEBUG_shaver_bufmgmt
|
||||||
fprintf(stderr, "looking for %s as %s\n", filename, filebuf);
|
fprintf(stderr, "looking for %s as %s\n", filename, filebuf);
|
||||||
#endif
|
#endif
|
||||||
file = fopen(filebuf, mode);
|
file = fopen(filebuf, mode);
|
||||||
|
@ -150,13 +161,13 @@ fopen_from_includes(const char *filename, const char *mode,
|
||||||
static struct input_callback_data *
|
static struct input_callback_data *
|
||||||
new_input_callback_data(const char *filename, IncludePathEntry *include_path)
|
new_input_callback_data(const char *filename, IncludePathEntry *include_path)
|
||||||
{
|
{
|
||||||
struct input_callback_data *new_data = malloc(sizeof *new_data);
|
struct input_callback_data *new_data = calloc(1, sizeof *new_data);
|
||||||
if (!new_data)
|
if (!new_data)
|
||||||
return NULL;
|
return NULL;
|
||||||
new_data->input = fopen_from_includes(filename, "r", include_path);
|
new_data->input = fopen_from_includes(filename, "r", include_path);
|
||||||
if (!new_data->input)
|
if (!new_data->input)
|
||||||
return NULL;
|
return NULL;
|
||||||
new_data->buf = malloc(INPUT_BUF_CHUNK);
|
new_data->buf = malloc(INPUT_BUF_CHUNK + 1); /* trailing NUL */
|
||||||
if (!new_data->buf) {
|
if (!new_data->buf) {
|
||||||
fclose(new_data->input);
|
fclose(new_data->input);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -182,7 +193,8 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
|
||||||
struct input_callback_stack *stack = user_data;
|
struct input_callback_stack *stack = user_data;
|
||||||
struct input_callback_data *data = stack->top, *new_data = NULL;
|
struct input_callback_data *data = stack->top, *new_data = NULL;
|
||||||
int rv, avail, copy;
|
int rv, avail, copy;
|
||||||
char *include_start, *ptr;
|
char *search, *check_point, *ptr, *end_copy, *raw_start, *comment_start,
|
||||||
|
*include_start;
|
||||||
|
|
||||||
switch(reason) {
|
switch(reason) {
|
||||||
case IDL_INPUT_REASON_INIT:
|
case IDL_INPUT_REASON_INIT:
|
||||||
|
@ -203,7 +215,6 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
|
||||||
assert(avail >= 0);
|
assert(avail >= 0);
|
||||||
|
|
||||||
if (!avail) {
|
if (!avail) {
|
||||||
char *comment_start = NULL, *include_start = NULL, *ptr;
|
|
||||||
data->point = data->buf;
|
data->point = data->buf;
|
||||||
|
|
||||||
/* fill the buffer */
|
/* fill the buffer */
|
||||||
|
@ -222,78 +233,94 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
|
||||||
stack->top = data;
|
stack->top = data;
|
||||||
IDL_file_set(data->filename, ++data->lineno);
|
IDL_file_set(data->filename, ++data->lineno);
|
||||||
IDL_inhibit_pop();
|
IDL_inhibit_pop();
|
||||||
|
data->f_include = INPUT_IN_NONE;
|
||||||
goto fill_start;
|
goto fill_start;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
data->buf[data->len] = 0;
|
||||||
/*
|
|
||||||
* strip comments
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX
|
|
||||||
* What if the last char in this block is '/' and the first in the
|
|
||||||
* next block is '*'? I'm not sure it matters, because I don't
|
|
||||||
* think there are any legal IDL syntaxes with '/' in them.
|
|
||||||
*
|
|
||||||
* XXX what about "/* " appearing in the IDL?
|
|
||||||
*/
|
|
||||||
if (!comment_start)
|
|
||||||
comment_start = strstr(data->buf, "/*");
|
|
||||||
while (comment_start) {
|
|
||||||
char *end = strstr(comment_start, "*/");
|
|
||||||
int comment_length;
|
|
||||||
int bytes_after_comment;
|
|
||||||
|
|
||||||
if (!end)
|
|
||||||
goto fill_buffer;
|
|
||||||
|
|
||||||
end += 2; /* star-slash */
|
|
||||||
comment_length = end - comment_start;
|
|
||||||
bytes_after_comment = data->buf + data->len - end;
|
|
||||||
|
|
||||||
/* found the end, move data around */
|
|
||||||
#ifdef DEBUG_shaver_bufmgmt
|
|
||||||
fprintf(stderr,
|
|
||||||
"FOUND COMMENT: (%d) %.*s, moving %d back\n",
|
|
||||||
comment_length, comment_length,
|
|
||||||
comment_start, bytes_after_comment);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memmove(comment_start, end, bytes_after_comment);
|
|
||||||
comment_start[bytes_after_comment] = '\0';
|
|
||||||
data->len -= comment_length;
|
|
||||||
|
|
||||||
#ifdef DEBUG_shaver_bufmgmt
|
|
||||||
fprintf(stderr, "new buffer:\n---\n%.*s\n---\n",
|
|
||||||
data->len, data->buf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* look for the next comment */
|
|
||||||
comment_start = strstr(data->buf, "/*");
|
|
||||||
|
|
||||||
} /* while(comment_start) */
|
|
||||||
|
|
||||||
/* we set avail here, because data->len is changed above */
|
|
||||||
|
|
||||||
avail = data->buf + data->len - data->point;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_point = data->point;
|
||||||
|
end_copy = data->buf + data->len;
|
||||||
/*
|
/*
|
||||||
* process includes
|
* When we're stripping comments and processing #includes,
|
||||||
|
* we need to be sure that we don't process anything inside
|
||||||
|
* \n%{ and \n%}. In order to simplify things, we only process
|
||||||
|
* comment, include or raw-block stuff when they're at the
|
||||||
|
* beginning of the block we're about to send (data->point).
|
||||||
|
* This makes the processing much simpler, since we can skip
|
||||||
|
* data->point ahead for comments and #include, and skip
|
||||||
|
* check_point ahead for raw blocks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
if (!(data->f_raw || data->f_comment || data->f_include)) {
|
||||||
* we only do #include magic at the beginning of the buffer.
|
/* look for first raw/comment/include */
|
||||||
* otherwise, we just set avail to cap the amount of data sent
|
|
||||||
* on this pass.
|
/* raw block */
|
||||||
*/
|
if ((raw_start = strstr(check_point, "\n%{"))) {
|
||||||
include_start = strstr(data->point, "#include \"");
|
end_copy = raw_start;
|
||||||
if (include_start == data->point) {
|
}
|
||||||
/* time to process the #include */
|
|
||||||
|
/* comment */
|
||||||
|
if ((comment_start = strstr(check_point, "/*")) &&
|
||||||
|
(!raw_start || comment_start < raw_start)) {
|
||||||
|
end_copy = comment_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* include */
|
||||||
|
if ((include_start = strstr(check_point, "#include")) &&
|
||||||
|
(!raw_start || include_start < raw_start) &&
|
||||||
|
(!comment_start || include_start < comment_start)) {
|
||||||
|
end_copy = include_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end_copy == raw_start)
|
||||||
|
data->f_raw = INPUT_IN_START;
|
||||||
|
|
||||||
|
else if (end_copy == comment_start)
|
||||||
|
data->f_comment = INPUT_IN_START;
|
||||||
|
|
||||||
|
else if (end_copy == include_start)
|
||||||
|
data->f_include = INPUT_IN_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((end_copy == data->buf || /* just found one at the start */
|
||||||
|
end_copy == data->buf + data->len /* left over */) &&
|
||||||
|
(data->f_raw || data->f_comment || data->f_include)) {
|
||||||
|
|
||||||
|
if (data->f_raw) {
|
||||||
|
ptr = strstr(check_point, "\n%}");
|
||||||
|
if (ptr) {
|
||||||
|
data->f_raw = INPUT_IN_NONE;
|
||||||
|
end_copy = ptr + 3;
|
||||||
|
#ifdef DEBUG_shaver_bufmgmt
|
||||||
|
fprintf(stderr, "RAW->%.*s<-RAW\n", end_copy - data->point,
|
||||||
|
data->point);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
assert(!data->f_comment && !data->f_include);
|
||||||
|
} else if (data->f_comment) {
|
||||||
|
/* XXX process doc comment */
|
||||||
|
ptr = strstr(check_point, "*/");
|
||||||
|
if (ptr) {
|
||||||
|
data->point = ptr + 2; /* star-slash */
|
||||||
|
#ifdef DEBUG_shaver_bufmgmt
|
||||||
|
fprintf(stderr, "COMMENT->%.*s<-COMMENT\n",
|
||||||
|
data->point - check_point, check_point);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
assert(!data->f_raw && !data->f_include);
|
||||||
|
} else if (data->f_include) {
|
||||||
|
/* process include */
|
||||||
const char *scratch;
|
const char *scratch;
|
||||||
char *filename = include_start + 10;
|
char *filename;
|
||||||
|
include_start = data->buf;
|
||||||
|
|
||||||
|
assert(!strncmp(include_start, "#include \"", 10));
|
||||||
|
filename = include_start + 10; /* skip #include " */
|
||||||
|
|
||||||
|
assert(filename < data->buf + data->len);
|
||||||
ptr = strchr(filename, '\"');
|
ptr = strchr(filename, '\"');
|
||||||
if (!ptr) {
|
if (!ptr) {
|
||||||
/* XXX report error */
|
/* XXX report error */
|
||||||
|
@ -303,12 +330,12 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
|
||||||
|
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
ptr = strrchr(filename, '.');
|
ptr = strrchr(filename, '.');
|
||||||
/* XXX is this a safe optimization? */
|
|
||||||
|
#ifdef DEBUG_shaver_bufmgmt
|
||||||
|
fprintf(stderr, "found #include %s\n", filename);
|
||||||
|
#endif
|
||||||
if (!g_hash_table_lookup(stack->includes, filename)) {
|
if (!g_hash_table_lookup(stack->includes, filename)) {
|
||||||
char *basename = filename;
|
char *basename = filename;
|
||||||
#ifdef DEBUG_shaver_includes
|
|
||||||
fprintf(stderr, "processing #include %s\n", filename);
|
|
||||||
#endif
|
|
||||||
filename = strdup(filename);
|
filename = strdup(filename);
|
||||||
ptr = strrchr(basename, '.');
|
ptr = strrchr(basename, '.');
|
||||||
if (ptr)
|
if (ptr)
|
||||||
|
@ -326,20 +353,16 @@ input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
|
||||||
IDL_file_get(&scratch, &data->lineno);
|
IDL_file_get(&scratch, &data->lineno);
|
||||||
data = stack->top = new_data;
|
data = stack->top = new_data;
|
||||||
IDL_file_set(data->filename, data->lineno);
|
IDL_file_set(data->filename, data->lineno);
|
||||||
|
#ifdef DEBUG_shaver_bufmgmt
|
||||||
|
fprintf(stderr, "processing #include %s\n", filename);
|
||||||
|
#endif
|
||||||
/* now continue getting data from new file */
|
/* now continue getting data from new file */
|
||||||
goto fill_start;
|
goto fill_start;
|
||||||
} else {
|
|
||||||
#ifdef DEBUG_shaver_includes
|
|
||||||
fprintf(stderr, "not processing #include %s again\n",
|
|
||||||
filename);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} else if (include_start) {
|
|
||||||
#ifdef DEBUG_shaver_includes
|
|
||||||
fprintf(stderr, "not processing #include yet\n");
|
|
||||||
#endif
|
|
||||||
avail = include_start - data->point;
|
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
|
||||||
|
avail = MIN(data->buf + data->len, end_copy) - data->point;
|
||||||
copy = MIN(avail, cb_data->fill.max_size);
|
copy = MIN(avail, cb_data->fill.max_size);
|
||||||
memcpy(cb_data->fill.buffer, data->point, copy);
|
memcpy(cb_data->fill.buffer, data->point, copy);
|
||||||
data->point += copy;
|
data->point += copy;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче