1 //////////////////////////////////////////////////////////////////////////////
2 //Copyright 2008
3 // Andrew Gacek, Steven Holte, Gopalan Nadathur, Xiaochu Qi, Zach Snow
4 //////////////////////////////////////////////////////////////////////////////
5 // This file is part of Teyjus. //
6 // //
7 // Teyjus is free software: you can redistribute it and/or modify //
8 // it under the terms of the GNU General Public License as published by //
9 // the Free Software Foundation, either version 3 of the License, or //
10 // (at your option) any later version. //
11 // //
12 // Teyjus is distributed in the hope that it will be useful, //
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
15 // GNU General Public License for more details. //
16 // //
17 // You should have received a copy of the GNU General Public License //
18 // along with Teyjus. If not, see <http://www.gnu.org/licenses/>. //
19 //////////////////////////////////////////////////////////////////////////////
20 #include <sys/stat.h>
21 #include <stdlib.h>
22 #include "../include/standardlib.h"
23 #include <stdio.h>
24 #include <string.h>
25 #include "file.h"
26 #include "../system/error.h"
27 #include "linker_message.h"
28
29 #define DEBUG(x) printf("%s\n",x)
30 #define SWAPENDIAN
31
32 char* LK_FILE_LinkCodeExt=".lp";
33 char* LK_FILE_ByteCodeExt=".lpo";
34
LK_FILE_OpenInput(char * modname,char * extension)35 int LK_FILE_OpenInput(char* modname, char* extension)
36 {
37 int fd;
38 char* tjpath;
39 char* tjpath_; /* We need a copy since strtok modifies its argument */
40 char* dir;
41 char* buf=(char *)EM_malloc(strlen(modname)+strlen(extension)+1);
42 sprintf(buf,"%s%s",modname,extension);
43
44 fd=open(buf,O_RDONLY|O_BINARY,0000);
45 if(fd==-1)
46 {
47 /* Restrictive hack: works only on Unix
48 * To be fixed with C, or, better, rewrite all the linker in OCaml
49 * to do this easily */
50 tjpath=getenv("TJPATH");
51 if (tjpath == NULL) tjpath=".";
52 tjpath_=strdup(tjpath);
53
54 dir=strtok(tjpath_,":");
55
56 while (dir != NULL) {
57 buf=(char *)EM_malloc(strlen(modname)+strlen(extension)+strlen(dir)+2);
58 sprintf(buf,"%s/%s%s",dir,modname,extension);
59 fd=open(buf,O_RDONLY|O_BINARY,0000);
60 if(fd!=-1)
61 return fd;
62 dir=strtok(NULL,":");
63 }
64
65 bad("Couldn't open file %s for reading.\n",buf);
66 EM_THROW(LK_LinkError);
67
68 }
69 return fd;
70 }
71
LK_FILE_OpenOutput(char * modname,char * extension)72 int LK_FILE_OpenOutput(char* modname, char* extension)
73 {
74 int fd;
75 char* buf=(char *)EM_malloc(strlen(modname)+strlen(extension)+1);
76 sprintf(buf,"%s%s",modname,extension);
77
78 fd=open(buf,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666);
79 if(fd==-1)
80 {
81 bad("Couldn't open file %s for writing.\n",buf);
82 EM_THROW(LK_LinkError);
83 }
84 return fd;
85 }
86
LK_FILE_xPipe(int fd[2])87 void LK_FILE_xPipe(int fd[2])
88 {
89 if(pipe(fd))
90 {
91 bad("Couldn't open pipe.\n");
92 EM_THROW(LK_LinkError);
93 }
94 }
95
LK_FILE_Close(int fd)96 void LK_FILE_Close(int fd)
97 {
98 close(fd);///\todo handle close error?
99 }
100
LK_FILE_GETWord(int fd)101 Word LK_FILE_GETWord(int fd)
102 {
103 Word tmp;
104 read(fd,&tmp,sizeof(tmp));
105 #if BYTE_ORDER == LITTLE_ENDIAN
106 # if __WORDSIZE == 32
107 return (Word)bswap_32((unsigned int)tmp);
108 # elif __WORDSIZE == 64
109 return bswap_64(tmp);
110 # endif
111 #elif BYTE_ORDER == BIG_ENDIAN
112 return tmp;
113 #endif
114 }
115
LK_FILE_GET4(int fd)116 INT4 LK_FILE_GET4(int fd)
117 {
118 INT4 tmp;
119 read(fd,&tmp,sizeof(tmp));
120 #if BYTE_ORDER == LITTLE_ENDIAN
121 return bswap_32(tmp);
122 #elif BYTE_ORDER == BIG_ENDIAN
123 return tmp;
124 #endif
125 }
126
LK_FILE_GET2(int fd)127 TwoBytes LK_FILE_GET2(int fd)
128 {
129 TwoBytes tmp;
130 read(fd,&tmp,sizeof(tmp));
131 #if BYTE_ORDER == LITTLE_ENDIAN
132 return bswap_16(tmp);
133 #elif BYTE_ORDER == BIG_ENDIAN
134 return tmp;
135 #endif
136 }
137
LK_FILE_GET1(int fd)138 Byte LK_FILE_GET1(int fd)
139 {
140 Byte tmp;
141 read(fd,&tmp,sizeof(tmp));
142 return tmp;
143 }
144
LK_FILE_GetString(int fd)145 char* LK_FILE_GetString(int fd)
146 {
147 char* tmp;
148 int size=LK_FILE_GET4(fd);
149 //fprintf(stderr, "Name:%d ",size);//DEBUG
150 tmp=(char *)EM_malloc(size+1);
151 read(fd,tmp,size);
152 tmp[size]='\0';
153 //fprintf(stderr, "\"%s\"\n",tmp);//DEBUG
154 return tmp;
155 }
156
LK_FILE_PUT1(int fd,Byte x)157 void LK_FILE_PUT1(int fd, Byte x)
158 {
159 write(fd,&x,sizeof(x));
160 }
161
LK_FILE_PUT2(int fd,TwoBytes x)162 void LK_FILE_PUT2(int fd, TwoBytes x)
163 {
164 #if BYTE_ORDER == LITTLE_ENDIAN
165 x=bswap_16(x);
166 #elif BYTE_ORDER == BIG_ENDIAN
167 #endif
168 write(fd,&x,sizeof(x));
169 }
170
LK_FILE_PUT4(int fd,INT4 x)171 void LK_FILE_PUT4(int fd, INT4 x)
172 {
173 #if BYTE_ORDER == LITTLE_ENDIAN
174 x=bswap_32(x);
175 #elif BYTE_ORDER == BIG_ENDIAN
176 #endif
177 write(fd,&x,sizeof(x));
178 }
179
LK_FILE_PUTN(int fd,void * data,int n)180 void LK_FILE_PUTN(int fd, void* data,int n)
181 {
182 write(fd,data,n);
183 }
184
LK_FILE_PUTWord(int fd,Word x)185 void LK_FILE_PUTWord(int fd, Word x)
186 {
187 #if BYTE_ORDER == LITTLE_ENDIAN
188 # if __WORDSIZE == 32
189 x=(Word)bswap_32((unsigned int)x);
190 # elif __WORDSIZE == 64
191 x=bswap_64(x);
192 # endif
193 #elif BYTE_ORDER == BIG_ENDIAN
194 #endif
195 write(fd,&x,sizeof(x));
196 }
197
LK_FILE_PutString(int fd,char * str)198 void LK_FILE_PutString(int fd, char* str)
199 {
200 int size=strlen(str);
201 LK_FILE_PUT4(fd,size);
202 write(fd,str,size);
203 }
204
205