aboutsummaryrefslogtreecommitdiff
path: root/src/pp.c
blob: db371181c39bf6a7afb1de4ab94a7ced44096585 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "include/pp.h"

pp_t* pp_init(char* src) {
   pp_t* pp;

   pp = ecalloc(1, sizeof(pp_t));

   pp->src = src;
   pp->psrc = (char*) emalloc(1);
   pp->psrc[0] = '\0';

   pp->state = PP_STATE_REG;

   return pp;
}

void pp_destroy(pp_t* pp) {
   free(pp);
}

void pp_cpy_char(pp_t* pp) {
   int plen = strlen(pp->psrc);
   pp->psrc = erealloc(pp->psrc, (plen + 2) * sizeof(char));

   pp->psrc[plen] = *pp->src;
   pp->psrc[plen + 1] = '\0';
}

void pp_do_reg(pp_t* pp) {
   switch (*pp->src) {
      case SYNTAX_COMMENT_DELIM:
         pp->state = PP_STATE_COM; 
         break;
      case SYNTAX_STR_DELIM:
         pp_cpy_char(pp);
         pp->state = PP_STATE_STR;
         break;
      case ' ': 
      case '\n':
      case '\r':
      case '\t':
         /* skip whitespace */
         break;

      default:
         pp_cpy_char(pp);
   }
}

void pp_do_str(pp_t* pp) {
   if (pp->state == PP_STATE_ESC) {
      pp_cpy_char(pp);
      pp->state = PP_STATE_STR;
   } else {
      if (*pp->src == SYNTAX_ESC) {
         pp_cpy_char(pp);
         pp->state = PP_STATE_ESC;
      } else if (*pp->src == SYNTAX_STR_DELIM) {
         pp_cpy_char(pp);
         pp->state = PP_STATE_REG;
      }
      else {
         pp_cpy_char(pp);
      }
   }
}

void pp_do_com(pp_t* pp) {
   if (*pp->src == SYNTAX_COMMENT_DELIM) {
      pp->state = PP_STATE_REG;
   }

   /* let pp_run skip chars in comments */
}

void pp_run(pp_t* pp) {
   while (*pp->src) {
      switch (pp->state) {
         case PP_STATE_REG:
            pp_do_reg(pp);
            break;
         case PP_STATE_STR:
         case PP_STATE_ESC:
            pp_do_str(pp);
            break;
         case PP_STATE_COM:
            pp_do_com(pp);
            break;
      }

      pp->src ++;
   }
}