Binit(&b, f, OWRITE);
Bprint(&b, "%s\n", thestring);
+ if(nffi > 0) {
+ int i;
+
+ if(package == nil) {
+ yyerror("#pragma ffi without #pragma package");
+ package = "_ffi_";
+ }
+ Bprint(&b, "\n$$ // ffi\n", thestring);
+ Bprint(&b, "package %s\n", package);
+ for(i=0; i<nffi; i++)
+ Bprint(&b, "//ffi %c %s %s %s\n", ffi[i].type, ffi[i].local, ffi[i].remote, ffi[i].path);
+ Bprint(&b, "$$\n\n$$\n\n");
+ }
Bprint(&b, "!\n");
outhist(&b);
// skip white space
p = *pp;
+again:
while(p < ep && (*p == ' ' || *p == '\t'))
p++;
if(p == ep)
p += 5;
else if(strncmp(p, "const ", 6) == 0)
p += 6;
- else{
+ else if(strncmp(p, "//", 2) == 0) {
+ p = memchr(p, '\n', ep - p);
+ if(p == nil)
+ return 0;
+ p++;
+ goto again;
+ } else {
fprint(2, "ar: confused in pkg data near <<%.20s>>\n", p);
errors++;
return -1;
typedef struct Term Term;
typedef struct Init Init;
typedef struct Bits Bits;
+typedef struct Ffi Ffi;
#define NHUNK 50000L
#define BUFSIZ 8192
Sym* castfr[NTYPE];
};
+struct Ffi
+{
+ char type;
+ char* local;
+ char* remote;
+ char* path;
+};
+
+EXTERN Ffi *ffi;
+EXTERN int nffi;
+EXTERN char* package;
+
EXTERN struct
{
Type* tenum; /* type of entire enum */
void pragfpround(void);
void pragtextflag(void);
void pragincomplete(void);
+void pragffi(void);
+void pragpackage(void);
/*
* calls to machine depend part
flagbits['X'] = flagbits['o'];
}
+static char*
+getquoted(void)
+{
+ int c;
+ char *t;
+ Rune r;
+
+ c = getnsc();
+ if(c != '"')
+ return nil;
+ t = fmtbuf;
+ for(;;) {
+ r = getr();
+ if(r == ' ' || r == '\n')
+ return nil;
+ if(r == '"')
+ break;
+ t += runetochar(t, &r);
+ }
+ *t = 0;
+ return strdup(fmtbuf);
+}
+
void
pragvararg(void)
{
Sym *s;
int n, c;
char *t;
- Rune r;
Type *ty;
if(!debug['F'])
cktype:
/*#pragma varargck type O int*/
- c = getnsc();
- if(c != '"')
+ t = getquoted();
+ if(t == nil)
goto bad;
- t = fmtbuf;
- for(;;) {
- r = getr();
- if(r == ' ' || r == '\n')
- goto bad;
- if(r == '"')
- break;
- t += runetochar(t, &r);
- }
- *t = 0;
- t = strdup(fmtbuf);
s = getsym();
if(s == S)
goto bad;
if(debug['f'])
print("%s incomplete\n", s->name);
}
+
+void
+pragffi(void)
+{
+ Sym *local, *remote, *type;
+ char *path;
+ Ffi *f;
+
+ type = getsym();
+ if(type == nil)
+ goto err;
+
+ local = getsym();
+ if(local == nil)
+ goto err;
+
+ remote = getsym();
+ if(remote == nil)
+ goto err;
+
+ path = getquoted();
+ if(path == nil)
+ goto err;
+
+ if(nffi%32 == 0)
+ ffi = realloc(ffi, (nffi+32)*sizeof ffi[0]);
+ f = &ffi[nffi++];
+ f->type = type->name[0];
+ f->local = local->name;
+ f->remote = remote->name;
+ f->path = path;
+ goto out;
+
+err:
+ yyerror("usage: #pragma ffi typechar local remote \"path\"");
+
+out:
+ while(getnsc() != '\n')
+ ;
+}
+
+void
+pragpackage(void)
+{
+ Sym *s;
+
+ s = getsym();
+ if(s == nil)
+ goto err;
+
+ package = s->name;
+ goto out;
+
+err:
+ yyerror("malformed #pragma package");
+
+out:
+ while(getnsc() != '\n')
+ ;
+}
+
;
}
+void
+pragffi(void)
+{
+ while(getnsc() != '\n')
+ ;
+}
+
+void
+pragpackage(void)
+{
+ while(getnsc() != '\n')
+ ;
+}
+
void
pragfpround(void)
{
continue;
}
if(ischr){
- if(c == '\\'){
+ if(c == '\\'){
base = allocn(base, len, 1);
base[len++] = c;
c = getc();
print("#expand %s %s\n", s->name, ob);
return;
}
-
+
nargs = (char)(*s->macro & ~VARMAC) - 1;
dots = *s->macro & VARMAC;
pragincomplete();
return;
}
+ if(s && strcmp(s->name, "ffi") == 0) {
+ pragffi();
+ return;
+ }
+ if(s && strcmp(s->name, "package") == 0) {
+ pragpackage();
+ return;
+ }
while(getnsc() != '\n')
;
return;
goto bad;
/*
- * put pragma-line in as a funny history
+ * put pragma-line in as a funny history
*/
c = strlen(symb) + 1;
hp = alloc(c);
while(*p0 == ' ' || *p0 == '\t' || *p0 == '\n')
p0++;
if(strncmp(p0, "package ", 8) != 0) {
- fprint(2, "%s: bad package section in %s\n", argv0, filename);
+ fprint(2, "%s: bad package section in %s - %s\n", argv0, filename, p0);
return;
}
p0 += 8;
return 0;
// prefix: (var|type|func|const)
- prefix = p;
-
prefix = p;
if(p + 6 > ep)
return -1;
goto again;
} else {
err:
- fprint(2, "%s: confused in pkg data near <<%.20s>>\n", argv0, prefix);
+ fprint(2, "%s: confused in pkg data near <<%.40s>>\n", argv0, prefix);
nerrors++;
return -1;
}