]> rtime.felk.cvut.cz Git - frescor/forb.git/blob - forb-idl/forb-idl-c-backend.c
Added redistribution of HELLO packets
[frescor/forb.git] / forb-idl / forb-idl-c-backend.c
1 #include "config.h"
2
3 #include "forb-idl-c-backend.h"
4 #include <stdio.h>
5 #include <string.h>
6 #include <ctype.h>
7 #include <errno.h>
8 #include <sys/stat.h>
9 #include <sys/types.h>
10
11 #include <glib/gstdio.h>
12
13 static FILE *out_for_pass(const char *input_filename, int pass, 
14                           OIDL_Run_Info *rinfo);
15
16 gboolean
17 forb_idl_output_c (IDL_tree       tree,
18                     OIDL_Run_Info *rinfo)
19 {
20   int i;
21   char *ctmp;
22   OIDL_C_Info ci;
23
24   ci.base_name = g_path_get_basename(rinfo->input_filename);
25   ctmp = strrchr(ci.base_name, '.');
26   g_assert(ctmp);
27   *ctmp = '\0';
28
29   ci.c_base_name = g_strdup(ci.base_name);
30   if(!isalpha((guchar)ci.c_base_name[0]))
31     ci.c_base_name[0] = '_';
32   for(i = 0; ci.c_base_name[i]; i++) {
33     if(!isalnum((guchar)ci.c_base_name[i])) ci.c_base_name[i] = '_';
34   }
35
36   ci.ext_dcls = g_string_new(NULL);
37
38   ci.do_impl_hack = 1;
39   ci.do_skel_defs = rinfo->do_skel_defs;
40   for(i = 0; i < OUTPUT_NUM_PASSES; i++) {
41     if( (1 << i) & rinfo->enabled_passes) {
42       ci.fh = out_for_pass(rinfo->input_filename, 1 << i, rinfo);
43       
44       switch(1 << i) {
45       case OUTPUT_STUBS:
46         forb_idl_output_c_stubs(tree, rinfo, &ci);
47         break;
48       case OUTPUT_SKELS:
49         forb_idl_output_c_skeletons(tree, rinfo, &ci);
50         break;
51       case OUTPUT_COMMON:
52         forb_idl_output_c_common(tree, rinfo, &ci);
53         break;
54       case OUTPUT_HEADERS:
55         forb_idl_output_c_headers(tree, rinfo, &ci);
56         break;
57       case OUTPUT_SKELIMPL:
58         forb_idl_output_c_skelimpl(tree, rinfo, &ci);
59         break;
60       case OUTPUT_IMODULE:
61         forb_idl_output_c_imodule(tree, rinfo, &ci);
62         break;
63       case OUTPUT_DEPS:
64         forb_idl_output_c_deps(tree, rinfo, &ci);
65         break;
66       }
67       fclose(ci.fh);
68     }
69   }
70   g_string_free(ci.ext_dcls,TRUE);
71
72   return TRUE;
73 }
74
75 char *
76 forb_idl_c_filename_for_pass (const char *input_filename, 
77                                int pass)
78 {
79         char *filename;
80         char *basename;
81         char *dot;
82         const char *tack_on = NULL;
83   
84         basename = g_path_get_basename (input_filename);
85         dot = strrchr (basename, '.');
86         if (dot != NULL)
87                 *dot = '\0';
88
89         switch (pass) {
90         case OUTPUT_STUBS:
91                 tack_on = "-stubs.c";
92                 break;
93         case OUTPUT_SKELS:
94                 tack_on = "-skels.c";
95                 break;
96         case OUTPUT_COMMON:
97                 tack_on = "-common.c";
98                 break;
99         case OUTPUT_HEADERS:
100                 tack_on = ".h";
101                 break;
102         case OUTPUT_SKELIMPL:
103                 tack_on = "-skelimpl.c";
104                 break;
105         case OUTPUT_IMODULE:
106                 tack_on = "-imodule.c";
107                 break;
108         default:
109                 g_error("Unknown output pass");
110                 break;
111         }
112
113         filename = g_strconcat (basename, tack_on, NULL);
114         g_free (basename);
115
116         return filename;
117 }
118
119 static FILE *
120 out_for_pass (const char    *input_filename,
121               int            pass,
122               OIDL_Run_Info *rinfo)
123 {
124         FILE *fp;
125         char *output_filename;
126         gchar *output_full_path = NULL;
127
128
129         if ((strlen(rinfo->output_directory)) && (!g_file_test (rinfo->output_directory, G_FILE_TEST_IS_DIR))) {
130                 g_error ("ouput directory '%s' does not exist",
131                          rinfo->output_directory);
132                 return NULL;
133         }
134         
135         if (pass == OUTPUT_DEPS) {
136                 if (!g_file_test (".deps", G_FILE_TEST_IS_DIR)) {
137                         if (g_mkdir (".deps", 0775) < 0) {
138                                 g_warning ("failed to create '.deps' directory '%s'",
139                                            g_strerror (errno));
140                                 return NULL;
141                         }
142                 }
143                 
144                 if (rinfo->deps_file)
145                         fp =  g_fopen (rinfo->deps_file, "w");
146                 else
147                         fp = NULL;
148
149                 if (fp == NULL) 
150                         g_warning ("failed to open '%s': %s\n",
151                                    rinfo->deps_file, g_strerror (errno));
152                 
153         } else {
154                 output_filename = forb_idl_c_filename_for_pass (input_filename, pass);
155                 output_full_path = g_build_path (G_DIR_SEPARATOR_S, rinfo->output_directory, output_filename, NULL);
156                 g_free (output_filename);
157
158                 fp = g_fopen (output_full_path, "w+");
159                 if (fp == NULL)
160                         g_error ("failed to fopen '%s': %s\n", output_full_path, g_strerror(errno));
161
162                 g_free (output_full_path);
163         }
164
165         return fp;
166 }