Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[svn] Split up output into several lists, so GLSL profile can insert …
…lines of text

 into earlier portions of the output (such as subroutines we need to build in
 response to labels, and global uniform declaration after we've declared the
 mainline, etc).

--HG--
branch : trunk
  • Loading branch information
icculus committed Mar 28, 2008
1 parent c04c29e commit 626043e
Showing 1 changed file with 63 additions and 34 deletions.
97 changes: 63 additions & 34 deletions mojoshader.c
Expand Up @@ -185,10 +185,16 @@ typedef enum
// A simple linked list of strings, so we can build the final output without
// realloc()ing for each new line, and easily insert lines into the middle
// of the output without much trouble.
typedef struct OutputList
typedef struct OutputListNode
{
char *str;
struct OutputList *next;
struct OutputListNode *next;
} OutputListNode;

typedef struct OutputList
{
OutputListNode head;
OutputListNode *tail;
} OutputList;


Expand Down Expand Up @@ -258,9 +264,11 @@ struct Context
MOJOSHADER_free free;
const uint32 *tokens;
uint32 tokencount;
OutputList output;
OutputList *output_tail;
int output_len; // total strlen; prevents walking the list just to malloc.
OutputList *output;
OutputList globals;
OutputList subroutines;
OutputList mainline;
int output_len; // total strlen; prevents walking the lists just to malloc.
int indent;
const char *endline;
int endline_len;
Expand Down Expand Up @@ -371,10 +379,12 @@ static inline int fail(Context *ctx, const char *reason)
static int output_line(Context *ctx, const char *fmt, ...) ISPRINTF(2,3);
static int output_line(Context *ctx, const char *fmt, ...)
{
OutputListNode *item = NULL;

if (isfail(ctx))
return FAIL; // we failed previously, don't go on...

OutputList *item = (OutputList *) ctx->malloc(sizeof (OutputList));
item = (OutputListNode *) ctx->malloc(sizeof (OutputListNode));
if (item == NULL)
return out_of_memory(ctx);

Expand Down Expand Up @@ -410,9 +420,11 @@ static int output_line(Context *ctx, const char *fmt, ...)
} // else

item->next = NULL;
ctx->output_tail->next = item;
ctx->output_tail = item;

ctx->output->tail->next = item;
ctx->output->tail = item;
ctx->output_len += len + ctx->endline_len;

return 0;
} // output_line

Expand Down Expand Up @@ -2521,9 +2533,10 @@ static Context *build_context(const char *profile,
ctx->tokencount = bufsize / sizeof (uint32);
ctx->endline = endline_str;
ctx->endline_len = strlen(ctx->endline);
ctx->output.str = NULL;
ctx->output.next = NULL;
ctx->output_tail = &ctx->output;
ctx->globals.tail = &ctx->globals.head;
ctx->subroutines.tail = &ctx->subroutines.head;
ctx->mainline.tail = &ctx->mainline.head;
ctx->output = &ctx->globals;

const int profileid = find_profile_id(profile);
ctx->profileid = profileid;
Expand All @@ -2536,49 +2549,65 @@ static Context *build_context(const char *profile,
} // build_context


static void free_output_list(MOJOSHADER_free f, OutputListNode *item)
{
while (item != NULL)
{
OutputListNode *next = item->next;
if (item->str != NULL)
f(item->str);
f(item);
item = next;
} // while
} // free_output_list


static void destroy_context(Context *ctx)
{
if (ctx != NULL)
{
MOJOSHADER_free f = ((ctx->free != NULL) ? ctx->free : internal_free);
OutputList *item = ctx->output.next;
while (item != NULL)
{
OutputList *next = item->next;
if (item->str != NULL)
f(item->str);
f(item);
item = next;
} // while

free_output_list(f, ctx->globals.head.next);
free_output_list(f, ctx->subroutines.head.next);
free_output_list(f, ctx->mainline.head.next);
if ((ctx->failstr != NULL) && (ctx->failstr != out_of_mem_str))
f((void *) ctx->failstr);
f(ctx);
} // if
} // destroy_context


static void append_list(char **_wptr, const char *endline,
const size_t endline_len, OutputListNode *item)
{
char *wptr = *_wptr;
while (item != NULL)
{
const size_t len = strlen(item->str);
memcpy(wptr, item->str, len);
wptr += len;
memcpy(wptr, endline, endline_len);
wptr += endline_len;
item = item->next;
} // while
*wptr = '\0';
*_wptr = wptr;
} // append_list


static char *build_output(Context *ctx)
{
char *retval = (char *) ctx->malloc(ctx->output_len + 1);
if (retval == NULL)
out_of_memory(ctx);
else
{
const char *endline = ctx->endline;
const size_t endline_len = ctx->endline_len;
const char *endl = ctx->endline;
const size_t endllen = ctx->endline_len;
char *wptr = retval;
OutputList *item = ctx->output.next;
while (item != NULL)
{
const size_t len = strlen(item->str);
memcpy(wptr, item->str, len);
wptr += len;
memcpy(wptr, endline, endline_len);
wptr += endline_len;
item = item->next;
} // while
*wptr = '\0';
append_list(&wptr, endl, endllen, ctx->globals.head.next);
append_list(&wptr, endl, endllen, ctx->subroutines.head.next);
append_list(&wptr, endl, endllen, ctx->mainline.head.next);
} // else

return retval;
Expand Down

0 comments on commit 626043e

Please sign in to comment.