rdlib.c
上传用户:yuppie_zhu
上传日期:2007-01-08
资源大小:535k
文件大小:6k
源码类别:

编译器/解释器

开发平台:

C/C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "rdoff.h"
  5. #include "rdlib.h"
  6. /*
  7.  * format of rdoff library files:
  8.  * repeat
  9.  *   null terminated module name (max 255 chars)
  10.  *   RDOFF module
  11.  * until eof
  12.  */
  13. /*
  14.  * TODO
  15.  *
  16.  * No support exists yet for special modules. But we aren't using
  17.  * any special modules yet. They are only defined now so that their
  18.  * existance doesn't break older versions of the linker... presently
  19.  * anything whose name begins with '.' is ignored.
  20.  */
  21. int rdl_error = 0;
  22. char *rdl_errors[5] = {
  23.     "no error","could not open file", "invalid file structure",
  24.     "file contains modules of an unsupported RDOFF version",
  25.     "module not found"
  26. };
  27. int rdl_verify(const char * filename)
  28. {
  29.     FILE    * fp = fopen(filename, "rb");
  30.     char    buf[257];
  31.     int     i;
  32.     long    length;
  33.     static char lastverified[256];
  34.     static int lastresult = -1;
  35.     if (lastresult != -1 && !strcmp(filename, lastverified))
  36. return lastresult;
  37.     strcpy(lastverified, filename);
  38.     if (!fp)
  39. return (rdl_error = lastresult = 1);
  40.     
  41.     while (!feof(fp))
  42.     {
  43. i = 0;
  44. while (fread(buf + i,1,1,fp) == 1 && buf[i] && i < 257)
  45.     i++;
  46. if (feof(fp)) break;
  47. fread(buf, 6, 1, fp);
  48. buf[6] = 0;
  49. if (buf[0] == '.') {
  50.     /*
  51.      * a special module, eg a directory.
  52.      * Format of such a module is defined to be:
  53.      *   six char type identifier (which we've already read)
  54.      *   long count bytes content
  55.      *   content
  56.      * so we can handle it uniformaly with RDOFF2 modules...
  57.      * do nothing here. :-)
  58.      */
  59. }
  60. else if (strncmp(buf, "RDOFF", 5)) {
  61.     return rdl_error = lastresult = 2;
  62. }
  63. else if (buf[5] != '2') {
  64.     return rdl_error = lastresult = 3;
  65. }
  66. fread(&length, 4, 1, fp);
  67. fseek(fp, length, SEEK_CUR); /* skip over the module */
  68.     }
  69.     fclose(fp);
  70.     return lastresult = 0;      /* library in correct format */
  71. }
  72. int rdl_open (struct librarynode * lib, const char * name)
  73. {
  74.     int i = rdl_verify(name);
  75.     if (i) return i;
  76.     lib->fp = NULL;
  77.     lib->name = strdup(name);
  78.     lib->referenced = 0;
  79.     lib->next = NULL;
  80.     return 0;
  81. }
  82. void rdl_close (struct librarynode * lib)
  83. {
  84.     if (lib->fp)
  85. fclose(lib->fp);
  86.     free(lib->name);
  87. }
  88. int rdl_searchlib (struct librarynode * lib,
  89.    const char * label, rdffile * f)
  90. {
  91.     char buf[512];
  92.     int i, t;
  93.     void * hdr;
  94.     rdfheaderrec * r;
  95.     long l;
  96.     rdl_error = 0;
  97.     lib->referenced ++;
  98.     if (! lib->fp)
  99.     {
  100. lib->fp = fopen(lib->name,"rb");
  101. if (! lib->fp) {
  102.     rdl_error = 1;
  103.     return 0;
  104. }
  105.     }
  106.     else
  107. rewind(lib->fp);
  108.     while (! feof(lib->fp) )
  109.     {
  110. /* 
  111.  * read the module name from the file, and prepend 
  112.  * the library name and '.' to it.
  113.  */
  114. strcpy(buf, lib->name);
  115. i = strlen(lib->name);
  116. buf[i++] = '.'; t = i;
  117. while (fread(buf + i,1,1,lib->fp) == 1 && buf[i] && i < 512)
  118.     i++;
  119. buf[i] = 0;
  120. if (feof(lib->fp)) break;
  121. if (!strcmp(buf + t, ".dir"))  /* skip over directory */
  122. {
  123.     fread (&l, 4, 1, lib->fp);
  124.     fseek (lib->fp, l, SEEK_CUR);
  125.     continue;
  126. }
  127. /*
  128.  * open the RDOFF module
  129.  */
  130. if ( rdfopenhere(f,lib->fp,&lib->referenced,buf) ) {
  131.     rdl_error = 16 * rdf_errno;
  132.     return 0;
  133. }
  134. /*
  135.  * read in the header, and scan for exported symbols
  136.  */
  137. hdr = malloc(f->header_len);
  138. rdfloadseg(f,RDOFF_HEADER,hdr);
  139. while ((r = rdfgetheaderrec(f)))
  140. {
  141.     if (r->type != 3) /* not an export */
  142. continue;
  143.     if (! strcmp(r->e.label, label) ) /* match! */
  144.     {
  145. free(hdr); /* reset to 'just open' */
  146. f->header_loc = NULL; /* state... */
  147. f->header_fp = 0;
  148. return 1;
  149.     }
  150. }
  151. /* find start of next module... */
  152. i = f->eof_offset;
  153. rdfclose(f);
  154. fseek(lib->fp,i,SEEK_SET);
  155.     }
  156.     /*
  157.      * close the file if nobody else is using it
  158.      */
  159.     lib->referenced --;
  160.     if (! lib->referenced)
  161.     {
  162. fclose(lib->fp);
  163. lib->fp = NULL;
  164.     }
  165.     return 0;
  166. }
  167. int rdl_openmodule (struct librarynode * lib, int moduleno, rdffile * f)
  168. {
  169.     char    buf[512];
  170.     int     i, cmod, t;
  171.     long    length;
  172.     lib->referenced++;
  173.     if (!lib->fp)
  174.     {
  175. lib->fp = fopen(lib->name, "rb");
  176. if (!lib->fp) {
  177.     lib->referenced--;
  178.     return (rdl_error = 1);   
  179. }
  180.     }
  181.     else
  182. rewind(lib->fp);
  183.     cmod = -1;
  184.     while (!feof(lib->fp))
  185.     {
  186. strcpy(buf, lib->name);
  187. i = strlen(buf); 
  188. buf[i++] = '.'; t = i;
  189. while (fread(buf + i,1,1,lib->fp) == 1 && buf[i] && i < 512)
  190.     i++;
  191. buf[i] = 0;
  192. if (feof(lib->fp)) break;
  193. if (buf[t] != '.') /* special module - not counted in the numbering */
  194.     cmod++;    /* of RDOFF modules - must be referred to by name */
  195. if (cmod == moduleno) {
  196.     rdl_error = 16 *
  197. rdfopenhere(f, lib->fp, &lib->referenced, buf);
  198.     lib->referenced--;
  199.     if (!lib->referenced) {
  200. fclose(lib->fp);
  201. lib->fp = NULL;
  202.     }
  203.     return rdl_error;
  204. }
  205. fread(buf, 6, 1, lib->fp);
  206. buf[6] = 0;
  207. if (buf[t] == '.') {
  208.     /* do nothing */
  209. }
  210. else if (strncmp(buf, "RDOFF", 5)) {
  211.     if (! --lib->referenced) {
  212. fclose(lib->fp);
  213. lib->fp = NULL;
  214.     }
  215.     return rdl_error = 2;
  216. }
  217. else if (buf[5] != '2') {
  218.     if (! --lib->referenced) {
  219. fclose(lib->fp);
  220. lib->fp = NULL;
  221.     }
  222.     return rdl_error = 3;
  223. }
  224. fread(&length, 4, 1, lib->fp);
  225. fseek(lib->fp, length, SEEK_CUR); /* skip over the module */
  226.     }
  227.     if (! --lib->referenced) {
  228. fclose(lib->fp);
  229. lib->fp = NULL;
  230.     }
  231.     return rdl_error = 4; /* module not found */
  232. }
  233. void rdl_perror(const char *apname, const char *filename)
  234. {
  235.     if (rdl_error >= 16)
  236. rdfperror(apname, filename);
  237.     else
  238. fprintf(stderr,"%s:%s:%sn",apname,filename,rdl_errors[rdl_error]);
  239. }