OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [Open8 Tools/] [open8_src/] [open8_as/] [include_file.c] - Blame information for rev 178

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 178 jshamlet
 
2
#include <ctype.h>
3
#include <stdio.h>
4
#include <stdlib.h>
5
#include <string.h>
6
 
7
#include "defines.h"
8
 
9
#include "include_file.h"
10
#include "pass_1.h"
11
#include "parse.h"
12
 
13
 
14
extern int ind, inz, i, unfolded_size, extra_definitions, d;
15
extern char *unfolded_buffer, emsg[256], tmp[4096];
16
extern FILE *file_out_ptr;
17
 
18
struct incbin_file_data *incbin_file_data_first = NULL, *ifd_tmp;
19
struct active_file_info *active_file_info_first = NULL, *active_file_info_last = NULL, *active_file_info_tmp;
20
struct file_name_info *file_name_info_first = NULL, *file_name_info_last = NULL, *file_name_info_tmp;
21
char *include_in_tmp = NULL, *tmp_a = NULL;
22
int include_in_tmp_size = 0, tmp_a_size = 0, file_name_id = 1, open_files = 0;
23
 
24
char *full_name = NULL;
25
int full_name_size = 0;
26
 
27
char *include_dir = NULL;
28
int include_dir_size = 0;
29
 
30
char *buffer = NULL;
31
int size = 0;
32
 
33
 
34
int create_full_name(char *dir, char *name) {
35
 
36
  char *t;
37
  int i;
38
 
39
 
40
  if (dir == NULL && name == NULL)
41
    return SUCCEEDED;
42
 
43
  /* compute the length of the new string */
44
  i = 0;
45
  if (dir != NULL)
46
    i += strlen(dir);
47
  if (name != NULL)
48
    i += strlen(name);
49
  i++;
50
 
51
  if (i > full_name_size) {
52
    t = realloc(full_name, i);
53
    if (t == NULL) {
54
      fprintf(stderr, "CREATE_FULL_NAME: Out of memory error.\n");
55
      return FAILED;
56
    }
57
    full_name = t;
58
    full_name_size = i;
59
  }
60
 
61
  if (dir != NULL) {
62
    strcpy(full_name, dir);
63
    if (name != NULL)
64
      strcat(full_name, name);
65
  }
66
  else
67
    strcpy(full_name, name);
68
 
69
  return SUCCEEDED;
70
}
71
 
72
 
73
int include_file(char *name) {
74
 
75
  static int first_load = 0;
76
  int file_size, id;
77
  char *tmp_b, *n;
78
  FILE *f;
79
 
80
 
81
  /* create the full output file name */
82
  if (create_full_name(include_dir, name) == FAILED)
83
    return FAILED;
84
 
85
  f = fopen(full_name, "rb");
86
  id = 0;
87
 
88
  if (f == NULL && (include_dir == NULL || include_dir[0] == 0)) {
89
    sprintf(emsg, "Error opening file \"%s\".\n", name);
90
    if (first_load == 0)
91
      fprintf(stderr, "INCLUDE_FILE: %s", emsg);
92
    else
93
      print_error(emsg, ERROR_INC);
94
    return FAILED;
95
  }
96
 
97
  /* if failed try to find the file in the current directory */
98
  if (f == NULL) {
99
    fprintf(stderr, "%s:%d: ", get_file_name(active_file_info_last->filename_id), active_file_info_last->line_current);
100
    fprintf(stderr, "INCLUDE_FILE: Could not open \"%s\", trying \"%s\"... ", full_name, name);
101
    f = fopen(name, "rb");
102
    id = 1;
103
  }
104
 
105
  if (f == NULL) {
106
    fprintf(stderr, "not found.\n");
107
    sprintf(emsg, "Error opening file \"%s\".\n", full_name);
108
    if (first_load == 0)
109
      fprintf(stderr, "INCLUDE_FILE: %s", emsg);
110
    else
111
      print_error(emsg, ERROR_INC);
112
    return FAILED;
113
  }
114
 
115
  if (id == 1) {
116
    fprintf(stderr, "found.\n");
117
    strcpy(full_name, name);
118
  }
119
 
120
  first_load = 1;
121
 
122
  if (extra_definitions == ON) {
123
    redefine("WLA_FILENAME", 0.0, name, DEFINITION_TYPE_STRING, strlen(name));
124
    redefine("wla_filename", 0.0, name, DEFINITION_TYPE_STRING, strlen(name));
125
  }
126
 
127
  fseek(f, 0, SEEK_END);
128
  file_size = ftell(f);
129
  fseek(f, 0, SEEK_SET);
130
 
131
  active_file_info_tmp = malloc(sizeof(struct active_file_info));
132
  if (active_file_info_tmp == NULL) {
133
    sprintf(emsg, "Out of memory while trying allocate error tracking data structure for file \"%s\".\n", full_name);
134
    print_error(emsg, ERROR_INC);
135
    return FAILED;
136
  }
137
  active_file_info_tmp->next = NULL;
138
 
139
  if (active_file_info_first == NULL) {
140
    active_file_info_first = active_file_info_tmp;
141
    active_file_info_last = active_file_info_tmp;
142
    active_file_info_tmp->prev = NULL;
143
  }
144
  else {
145
    active_file_info_tmp->prev = active_file_info_last;
146
    active_file_info_last->next = active_file_info_tmp;
147
    active_file_info_last = active_file_info_tmp;
148
  }
149
 
150
  active_file_info_tmp->line_current = 1;
151
 
152
  /* name */
153
  file_name_info_tmp = file_name_info_first;
154
  id = 0;
155
  while (file_name_info_tmp != NULL) {
156
    if (strcmp(file_name_info_tmp->name, full_name) == 0) {
157
      id = file_name_info_tmp->id;
158
      active_file_info_tmp->filename_id = id;
159
      break;
160
    }
161
    file_name_info_tmp = file_name_info_tmp->next;
162
  }
163
 
164
  if (id == 0) {
165
    file_name_info_tmp = malloc(sizeof(struct file_name_info));
166
    n = malloc(strlen(full_name)+1);
167
    if (file_name_info_tmp == NULL || n == NULL) {
168
      if (file_name_info_tmp != NULL)
169
        free(file_name_info_tmp);
170
      if (n != NULL)
171
        free(n);
172
      sprintf(emsg, "Out of memory while trying allocate info structure for file \"%s\".\n", full_name);
173
      print_error(emsg, ERROR_INC);
174
      return FAILED;
175
    }
176
    file_name_info_tmp->next = NULL;
177
 
178
    if (file_name_info_first == NULL) {
179
      file_name_info_first = file_name_info_tmp;
180
      file_name_info_last = file_name_info_tmp;
181
    }
182
    else {
183
      file_name_info_last->next = file_name_info_tmp;
184
      file_name_info_last = file_name_info_tmp;
185
    }
186
 
187
    strcpy(n, full_name);
188
    file_name_info_tmp->name = n;
189
    active_file_info_tmp->filename_id = file_name_id;
190
    file_name_info_tmp->id = file_name_id;
191
    file_name_id++;
192
  }
193
 
194
  /* reallocate buffer */
195
  if (include_in_tmp_size < file_size) {
196
 
197
    if (include_in_tmp != NULL)
198
      free(include_in_tmp);
199
 
200
    include_in_tmp = malloc(sizeof(char) * file_size);
201
    if (include_in_tmp == NULL) {
202
      sprintf(emsg, "Out of memory while trying to allocate room for \"%s\".\n", full_name);
203
      print_error(emsg, ERROR_INC);
204
      return FAILED;
205
    }
206
 
207
    include_in_tmp_size = file_size;
208
  }
209
 
210
  /* read the whole file into a buffer */
211
  fread(include_in_tmp, 1, file_size, f);
212
  fclose(f);
213
 
214
  if (size == 0) {
215
    buffer = malloc(sizeof(char) * (file_size + 4));
216
    if (buffer == NULL) {
217
      sprintf(emsg, "Out of memory while trying to allocate room for \"%s\".\n", full_name);
218
      print_error(emsg, ERROR_INC);
219
      return FAILED;
220
    }
221
 
222
    /* preprocess */
223
    preprocess_file(include_in_tmp, include_in_tmp + file_size, buffer, &size, full_name);
224
 
225
    buffer[size++] = 0xA;
226
    buffer[size++] = '.';
227
    buffer[size++] = 'E';
228
    buffer[size++] = ' ';
229
 
230
    open_files++;
231
 
232
    return SUCCEEDED;
233
  }
234
 
235
  tmp_b = malloc(sizeof(char) * (size + file_size + 4));
236
  if (tmp_b == NULL) {
237
    sprintf(emsg, "Out of memory while trying to expand the project to incorporate file \"%s\".\n", full_name);
238
    print_error(emsg, ERROR_INC);
239
    return FAILED;
240
  }
241
 
242
  /* reallocate tmp_a */
243
  if (tmp_a_size < file_size) {
244
 
245
    if (tmp_a != NULL)
246
      free(tmp_a);
247
 
248
    tmp_a = malloc(sizeof(char) * (file_size + 4));
249
    if (tmp_a == NULL) {
250
      sprintf(emsg, "Out of memory while allocating new room for \"%s\".\n", full_name);
251
      print_error(emsg, ERROR_INC);
252
      return FAILED;
253
    }
254
 
255
    tmp_a_size = file_size + 4;
256
  }
257
 
258
  /* preprocess */
259
  inz = 0;
260
  preprocess_file(include_in_tmp, include_in_tmp + file_size, tmp_a, &inz, full_name);
261
 
262
  tmp_a[inz++] = 0xA;
263
  tmp_a[inz++] = '.';
264
  tmp_a[inz++] = 'E';
265
  tmp_a[inz++] = ' ';
266
 
267
  open_files++;
268
 
269
  memcpy(tmp_b, buffer, i);
270
  memcpy(tmp_b + i, tmp_a, inz);
271
  memcpy(tmp_b + i + inz, buffer + i, size - i);
272
 
273
  free(buffer);
274
 
275
  size += inz;
276
  buffer = tmp_b;
277
 
278
  return SUCCEEDED;
279
}
280
 
281
 
282
int incbin_file(char *name, int *id, int *swap, int *skip, int *read) {
283
 
284
  struct incbin_file_data *ifd;
285
  char *in_tmp, *n;
286
  int file_size, q;
287
  FILE *f;
288
 
289
 
290
  /* create the full output file name */
291
  if (create_full_name(include_dir, name) == FAILED)
292
    return FAILED;
293
 
294
  f = fopen(full_name, "rb");
295
  q = 0;
296
 
297
  if (f == NULL && (include_dir == NULL || include_dir[0] == 0)) {
298
    sprintf(emsg, "Error opening file \"%s\".\n", name);
299
    print_error(emsg, ERROR_INB);
300
    return FAILED;
301
  }
302
 
303
  /* if failed try to find the file in the current directory */
304
  if (f == NULL) {
305
    fprintf(stderr, "%s:%d: ", get_file_name(active_file_info_last->filename_id), active_file_info_last->line_current);
306
    fprintf(stderr, "INCBIN_FILE: Could not open \"%s\", trying \"%s\"... ", full_name, name);
307
    f = fopen(name, "rb");
308
    q = 1;
309
  }
310
 
311
  if (f == NULL) {
312
    fprintf(stderr, "not found.\n");
313
    sprintf(emsg, "Error opening file \"%s\".\n", full_name);
314
    print_error(emsg, ERROR_INB);
315
    return FAILED;
316
  }
317
 
318
  if (q == 1) {
319
    fprintf(stderr, "found.\n");
320
    strcpy(full_name, name);
321
  }
322
 
323
  fseek(f, 0, SEEK_END);
324
  file_size = ftell(f);
325
  fseek(f, 0, SEEK_SET);
326
 
327
  ifd = (struct incbin_file_data *)malloc(sizeof(struct incbin_file_data));
328
  n = malloc(sizeof(char) * (strlen(full_name)+1));
329
  in_tmp = (char *)malloc(sizeof(char) * file_size);
330
  if (ifd == NULL || n == NULL || in_tmp == NULL) {
331
    if (ifd != NULL)
332
      free(ifd);
333
    if (n != NULL)
334
      free(n);
335
    if (in_tmp != NULL)
336
      free(in_tmp);
337
    sprintf(emsg, "Out of memory while allocating data structure for \"%s\".\n", full_name);
338
    print_error(emsg, ERROR_INB);
339
    return FAILED;
340
  }
341
 
342
  /* read the whole file into a buffer */
343
  fread(in_tmp, 1, file_size, f);
344
  fclose(f);
345
 
346
  /* complete the structure */
347
  ifd->next = NULL;
348
  ifd->size = file_size;
349
  strcpy(n, name);
350
  ifd->name = n;
351
  ifd->data = in_tmp;
352
 
353
  /* find the index */
354
  q = 0;
355
  if (incbin_file_data_first != NULL) {
356
    ifd_tmp = incbin_file_data_first;
357
    while (ifd_tmp->next != NULL && strcmp(ifd_tmp->name, name) != 0) {
358
      ifd_tmp = ifd_tmp->next;
359
      q++;
360
    }
361
    if (ifd_tmp->next == NULL) {
362
      ifd_tmp->next = ifd;
363
      q++;
364
    }
365
  }
366
  else
367
    incbin_file_data_first = ifd;
368
 
369
  *id = q;
370
 
371
  /* SKIP bytes? */
372
  if (compare_next_token("SKIP", 4) == FAILED)
373
    *skip = 0;
374
  else {
375
    skip_next_token();
376
    inz = input_number();
377
    if (inz != SUCCEEDED) {
378
      print_error(".INCBIN needs the amount of skipped bytes.\n", ERROR_DIR);
379
      return FAILED;
380
    }
381
 
382
    *skip = d;
383
  }
384
 
385
  /* READ bytes? */
386
  if (compare_next_token("READ", 4) == FAILED)
387
    *read = file_size - *skip;
388
  else {
389
    skip_next_token();
390
    inz = input_number();
391
    if (inz != SUCCEEDED) {
392
      print_error(".INCBIN needs the amount of bytes for reading.\n", ERROR_DIR);
393
      return FAILED;
394
    }
395
 
396
    *read = d;
397
  }
398
 
399
  /* SWAP bytes? */
400
  if (compare_next_token("SWAP", 4) == FAILED)
401
    *swap = 0;
402
  else {
403
    if ((*read & 1) == 1) {
404
      sprintf(emsg, "File \"%s\" size is odd (%d)! Cannot perform SWAP.\n", full_name, *read);
405
      print_error(emsg, ERROR_INB);
406
      return FAILED;
407
    }
408
    *swap = 1;
409
    skip_next_token();
410
  }
411
 
412
  /* FSIZE? */
413
  if (compare_next_token("FSIZE", 5) == SUCCEEDED) {
414
    skip_next_token();
415
 
416
    /* get the definition label */
417
    if (get_next_token() == FAILED)
418
      return FAILED;
419
 
420
    add_a_new_definition(tmp, (double)file_size, NULL, DEFINITION_TYPE_VALUE, 0);
421
  }
422
 
423
  if (*skip + *read > file_size) {
424
    sprintf(emsg, "Overreading file \"%s\".\n", full_name);
425
    print_error(emsg, ERROR_INB);
426
    return FAILED;
427
  }
428
 
429
  return SUCCEEDED;
430
}
431
 
432
 
433
char get_file_name_error[] = "GET_FILE_NAME: Internal error.";
434
 
435
 
436
char *get_file_name(int id) {
437
 
438
  struct file_name_info *f;
439
 
440
 
441
  f = file_name_info_first;
442
  while (f != NULL) {
443
    if (id == f->id)
444
      return f->name;
445
    f = f->next;
446
  }
447
 
448
  return get_file_name_error;
449
}
450
 
451
 
452
int print_file_names(void) {
453
 
454
  struct incbin_file_data *d;
455
  struct file_name_info *f;
456
 
457
 
458
  f = file_name_info_first;
459
  d = incbin_file_data_first;
460
 
461
  /* handle the main file name differently */
462
  if (f != NULL) {
463
    if (f->next != NULL || d != NULL)
464
      fprintf(stderr, "%s \\\n", f->name);
465
    else
466
      fprintf(stderr, "%s\n", f->name);
467
    f = f->next;
468
  }
469
 
470
  /* included files */
471
  while (f != NULL) {
472
    if (f->next != NULL || d != NULL)
473
      fprintf(stderr, "\t%s \\\n", f->name);
474
    else
475
      fprintf(stderr, "\t%s\n", f->name);
476
    f = f->next;
477
  }
478
 
479
  /* incbin files */
480
  while (d != NULL) {
481
    if (d->next != NULL)
482
      fprintf(stderr, "\t%s \\\n", d->name);
483
    else
484
      fprintf(stderr, "\t%s\n", d->name);
485
    d = d->next;
486
  }
487
 
488
  return SUCCEEDED;
489
}
490
 
491
 
492
/* the mystery preprocessor - touch it and prepare for trouble ;) the preprocessor
493
   removes as much white space as possible from the source file. this is to make
494
   the parsing of the file, that follows, simpler. */
495
int preprocess_file(char *c, char *d, char *o, int *s, char *f) {
496
 
497
  register int t = 0, z = 0;
498
#if defined(W65816) || defined(SPC700)
499
  register int u = 0;
500
#endif
501
  char *e;
502
 
503
 
504
  e = o + (*s);
505
  while (c < d) {
506
    switch (*c) {
507
    case ';':
508
      /* clear a commented line */
509
      c++;
510
      for ( ; c < d && *c != 0x0A && *c != 0x0D; c++);
511
      e--;
512
      for ( ; e > o && *e == ' '; e--);
513
      if (e < o)
514
        e = o;
515
      else if (*e != ' ')
516
        e++;
517
      break;
518
    case '*':
519
      if (t == 0) {
520
        /* clear a commented line */
521
        c++;
522
        for ( ; c < d && *c != 0x0A && *c != 0x0D; c++);
523
      }
524
      else {
525
        /* multiplication! */
526
        c++;
527
        *e = '*';
528
        e++;
529
        t = 1;
530
      }
531
      break;
532
    case '/':
533
      if (*(c + 1) == '*') {
534
        /* remove an ANSI C -style block comment */
535
        t = 0;
536
        c += 2;
537
        while (t == 0) {
538
          for ( ; c < d && *c != '/' && *c != 0x0A; c++);
539
          if (c >= d) {
540
            sprintf(emsg, "Comment wasn't terminated properly in file \"%s\".\n", f);
541
            print_error(emsg, ERROR_INC);
542
            return FAILED;
543
          }
544
          if (*c == 0x0A) {
545
            *e = 0x0A;
546
            e++;
547
          }
548
          if (*c == '/' && *(c - 1) == '*') {
549
            t = 1;
550
          }
551
          c++;
552
        }
553
        e--;
554
        for ( ; e > o && *e == ' '; e--);
555
        if (e < o)
556
          e = o;
557
        else if (*e != ' ')
558
          e++;
559
      }
560
      else {
561
        c++;
562
        *e = '/';
563
        e++;
564
        t = 1;
565
      }
566
      break;
567
    case ':':
568
      /* finding a label resets the counters */
569
      c++;
570
      *e = ':';
571
      e++;
572
      t = 0;
573
      break;
574
    case 0x09:
575
    case ' ':
576
      /* remove extra white space */
577
      c++;
578
      *e = ' ';
579
      e++;
580
      for ( ; c < d && (*c == ' ' || *c == 0x09); c++);
581
      t = 1;
582
      if (z == 1)
583
        z = 2;
584
      break;
585
    case 0x0A:
586
      /* take away white space from the end of the line */
587
      c++;
588
      e--;
589
      for ( ; *e == ' '; e--);
590
      e++;
591
      *e = 0x0A;
592
      e++;
593
      t = 0;
594
      z = 0;
595
#if defined(W65816) || defined(SPC700)
596
      u = 0;
597
#endif
598
      break;
599
    case 0x0D:
600
      c++;
601
      break;
602
    case '\'':
603
      if (*(c + 2) == '\'') {
604
        *e = '\'';
605
        c++;
606
        e++;
607
        *e = *c;
608
        c++;
609
        e++;
610
        *e = '\'';
611
        c++;
612
        e++;
613
      }
614
      else {
615
        *e = '\'';
616
        c++;
617
        e++;
618
      }
619
      t = 1;
620
      break;
621
    case '"':
622
      /* don't alter the strings */
623
      *e = '"';
624
      c++;
625
      e++;
626
      t = 0;
627
      while (t == 0) {
628
        for ( ; c < d && *c != '"'; ) {
629
          *e = *c;
630
          c++;
631
          e++;
632
        }
633
        if (*c == '"' && *(c - 1) != '\\')
634
          t = 1;
635
        else {
636
          *e = '"';
637
          c++;
638
          e++;
639
        }
640
      }
641
      *e = '"';
642
      c++;
643
      e++;
644
      break;
645
#if !defined(W65816) && !defined(SPC700)
646
    case '[':
647
      /* change '[' to '(' */
648
#endif
649
    case '(':
650
      *e = '(';
651
      c++;
652
      e++;
653
      for ( ; c < d && (*c == ' ' || *c == 0x09); c++);
654
      t = 1;
655
      break;
656
#if !defined(W65816) && !defined(SPC700)
657
    case ']':
658
      /* change ']' to ')' */
659
#endif
660
    case ')':
661
      /* go back? */
662
      if (t == 1 && *(e - 1) == ' ')
663
        e--;
664
      *e = ')';
665
      c++;
666
      e++;
667
      t = 1;
668
      break;
669
#if defined(W65816) || defined(SPC700)
670
    case '[':
671
      *e = *c;
672
      c++;
673
      e++;
674
      t = 1;
675
      u = 1;
676
      break;
677
#endif
678
    case ',':
679
    case '+':
680
    case '-':
681
      if (t == 0) {
682
        for ( ; c < d && (*c == '+' || *c == '-'); c++, e++)
683
          *e = *c;
684
        t = 1;
685
      }
686
      else {
687
#if defined(W65816) || defined(SPC700)
688
        /* go back? */
689
        if (*(e - 1) == ' ' && u == 1)
690
          e--;
691
#else
692
        /* go back? */
693
        if ((z == 3 || *c == ',') && *(e - 1) == ' ')
694
          e--;
695
#endif
696
        *e = *c;
697
        c++;
698
        e++;
699
        for ( ; c < d && (*c == ' ' || *c == 0x09); c++);
700
        t = 1;
701
      }
702
      break;
703
    default:
704
      *e = *c;
705
      c++;
706
      e++;
707
      if (z == 0)
708
        z = 1;
709
      else if (z == 2)
710
        z = 3;
711
      t = 1;
712
      break;
713
    }
714
  }
715
 
716
  *s = e - o;
717
 
718
  return SUCCEEDED;
719
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.