home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************************
- *
- * C O M P . C
- * -----------
- *
- * Description:
- * Compile a FRM-file to C-code.
- *
- * Included functions:
- * main - Main function
- *
- * Revision:
- * Ver Date By Reason
- * --- ---- -- ------
- * 1.00 900619 Lars Berntzon Created
- *
- ******************************************************************************/
-
- #include "config.h"
-
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <assert.h>
- #include <signal.h>
- #ifdef STDLIB_H
- #include <stdlib.h>
- #endif
- #ifdef MALLOC_H
- #include <malloc.h>
- #endif
-
- #include "token.h"
- #include "comp.h"
-
- struct list list;
- char version[] = "1.1";
- int n_errors = 0;
- int n_warnings = 0;
-
- extern int cleanup();
-
- static int found_picture();
- static int found_event();
- static int found_viewport();
- static int found_ccode();
-
- static int previous_x, previous_y;
-
- static struct lookup_s lookup[] = { /* Aviable commands at top level */
- "PICTURE", found_picture,
- "EVENT", found_event,
- "VIEWPORT", found_viewport,
- "CCODE", found_ccode
- };
-
- #ifdef VOID_MAIN
- void main(int argc, char *argv[])
- #else
- main(int argc, char *argv[])
- #endif
- {
- char token [TOKENSIZE];
- int i;
-
- if (argc != 2) usage();
-
- if (OpenTok(argv[1]) == NULL) fatal("Failed to open file");
-
- signal(SIGINT, (SIGNAL_TYPE)cleanup);
- signal(SIGFPE, (SIGNAL_TYPE)cleanup);
-
- while(GetTokNC(token) != NULL) {
- for (i = 0; i < N_CMDS; i++) {
- if (strequ(token, lookup[i].cmd) == 0)
- break;
- }
- if (i < N_CMDS) {
- (*lookup[i].func)();
- }
- else {
- error("Unknown command");
- }
- }
-
- if (n_errors) {
- fprintf(stderr, "%d errors found.\n", n_errors);
- #ifdef VOID_MAIN
- return;
- #else
- return 1;
- #endif
- }
-
- /*
- * Generate C-code.
- */
- output();
-
- #ifdef VOID_MAIN
- return;
- #else
- return 0;
- #endif
- }
-
- static int found_viewport()
- {
- link((struct link **)&list.viewport, &get_viewport()->link, TYPE_VIEWPORT);
- return OK;
- }
- static int found_picture()
- {
- link((struct link **)&list.picture, &get_picture()->link, TYPE_PICTURE);
- return OK;
- }
- static int found_event()
- {
- link((struct link **)&list.event, &get_event()->link, TYPE_EVENT);
- return OK;
- }
- static int found_ccode()
- {
- link((struct link **)&list.ccode, &get_ccode()->link, TYPE_CCODE);
- return OK;
- }
-
- /******************************************************************************/
- int strequ(char *s1, char *s2)
- {
- while(*s1 && toupper(*s1) == toupper(*s2))
- s1++, s2++;
-
- return toupper(*s1) - toupper(*s2);
- }
-
- void usage(void)
- {
- fprintf(stderr, "Usage: comp <file>\n");
- exit(1);
- }
-
- void fatal(char *str)
- {
- fprintf(stderr, "fatal: %s\n", str);
- exit(1);
- }
-
- void error(char *str)
- {
- static int old_line;
- /*
- * Maximize to one error per line.
- */
- if (line > old_line) {
- n_errors++;
- old_line = line;
- fprintf(stderr, "error line %d: %s\n", line, str);
- }
- }
-
- void *_memalloc(char *file, int line, int size)
- {
- void *p;
- if ((p = malloc(size)) == NULL) {
- fprintf(stderr, "*** %s %d out of memory ***\n", file, line);
- exit(1);
- }
- memset(p, 0, size);
-
- return p;
- }
-
- void link(struct link **head, struct link *item, int type)
- {
- if (item == NULL) return;
-
- item->type = type;
-
- /*
- * Sort by name if aviable, otherwise last in list.
- */
- if (item->name) {
- for(; *head != NULL; head = &(*head)->next) {
- if (strequ((*head)->name, item->name) > 0) break;
- }
- }
- else {
- for(; *head != NULL; head = & (*head)->next)
- ;
- }
-
- item->next = *head;
- *head = item;
- }
-
- struct link *find_name(struct link *first, char *name)
- {
- if (name == NULL) return NULL;
-
- for(; first != NULL; first = first->next) {
- if (first->name != NULL && strequ(name, first->name) == 0) break;
- }
-
- return first;
- }
-
- void link_name(struct link *item, char *name)
- {
- if (item == NULL || name == NULL) return;
-
- item->name = memalloc(strlen(name) + 1);
- strcpy(item->name, name);
- }
-
- GetPos(int *x, int *y)
- {
- char token[TOKENSIZE];
- char sign = 0;
-
- if (GetTokNC(token) == NULL) return FAIL;
-
- if (token[0] == '+' || token[0] == '-') {
- sign = token[0];
- if (GetTokNC(token) == NULL) return FAIL;
- }
-
- if (!isdigit(token[0])) return FAIL;
-
- *x = atoi(token);
- if (sign) *x = previous_x + (sign == '-' ? - *x : *x);
- sign = 0;
-
- if (GetTokNC(token) == NULL || strcmp(token, ",")) return FAIL;
-
- if (GetTokNC(token) == NULL) return FAIL;
-
- if (token[0] == '+' || token[0] == '-') {
- sign = token[0];
- if (GetTokNC(token) == NULL) return FAIL;
- }
- if (!isdigit(token[0])) return FAIL;
-
- *y = atoi(token);
- if (sign) *y = previous_y + (sign == '-' ? - *y : *y);
- sign = 0;
-
- previous_x = *x;
- previous_y = *y;
-
- return OK;
- }
-
- cleanup()
- {
- struct viewport *vp;
- struct picture *pp;
- struct event *ep;
- struct ccode *cp;
-
- for(vp = list.viewport; vp != NULL; vp = unget_viewport(vp))
- ;
-
- for(pp = list.picture; pp != NULL; pp = unget_picture(pp))
- ;
-
- for(ep = list.event; ep != NULL; ep = unget_event(ep))
- ;
-
- for(cp = list.ccode; cp != NULL; cp = unget_ccode(cp))
- ;
-
- exit(1);
-
- return 0;
- }
-