/* * Read a list of parameters. Each parameter is a name and a type. * The list ends with a ')'. We have already read the '('. */ static struct params * read_params() { char *token; struct params *ret, **pp, *p; ret = NULL; pp = &ret; token = read_token_no_eof(); if (strcmp(token, ")") != 0) { while (1) { p = xmalloc(sizeof(struct params)); p->name = token; p->type = read_type(); p->next = NULL; *pp = p; pp = &p->next; token = read_token_no_eof(); if (strcmp(token, ",") != 0) break; token = read_token_no_eof(); } } if (strcmp(token, ")") != 0) { sysfatal("%s:%ud: expected '('\n", file, lineno); } return ret; }
/* Read the package clause, and return the package name. */ static char * read_package(void) { char *token; token = read_token_no_eof(); if (strcmp(token, "package") != 0) { fprintf(stderr, "%s:%u: expected \"package\", got \"%s\"\n", file, lineno, token); exit(1); } return read_token_no_eof(); }
/* Read the package clause, and return the package name. */ static char * read_package(void) { char *token; token = read_token_no_eof(); if (token == NULL) sysfatal("%s:%ud: no token\n", file, lineno); if (strcmp(token, "package") != 0) { sysfatal("%s:%ud: expected \"package\", got \"%s\"\n", file, lineno, token); } return read_token_no_eof(); }
/* Read a type in Go syntax and return a type in C syntax. We only permit basic types and pointers. */ static char * read_type(void) { char *p, *op, *q; int pointer_count; unsigned int len; p = read_token_no_eof(); if (*p != '*') return p; op = p; pointer_count = 0; while (*p == '*') { ++pointer_count; ++p; } len = strlen(p); q = xmalloc(len + pointer_count + 1); memcpy(q, p, len); while (pointer_count > 0) { q[len] = '*'; ++len; --pointer_count; } q[len] = '\0'; free(op); return q; }
/* Read a list of parameters. Each parameter is a name and a type. The list ends with a ')'. We have already read the '('. */ static struct params * read_params(int *poffset) { char *token; struct params *ret, **pp, *p; int offset, size, rnd; ret = NULL; pp = &ret; token = read_token_no_eof(); offset = 0; if (strcmp(token, ")") != 0) { while (1) { p = xmalloc(sizeof(struct params)); p->name = token; p->type = read_type(); p->next = NULL; *pp = p; pp = &p->next; size = type_size(p->type); rnd = size; if(rnd > structround) rnd = structround; if(offset%rnd) offset += rnd - offset%rnd; offset += size; token = read_token_no_eof(); if (strcmp(token, ",") != 0) break; token = read_token_no_eof(); } } if (strcmp(token, ")") != 0) { fprintf(stderr, "%s:%u: expected '('\n", file, lineno); exit(1); } if (poffset != NULL) *poffset = offset; return ret; }
/* Read a function header. This reads up to and including the initial '{' character. Returns 1 if it read a header, 0 at EOF. */ static int read_func_header(char **name, struct params **params, int *paramwid, struct params **rets) { int lastline; char *token; lastline = -1; while (1) { token = read_token(); if (token == NULL) return 0; if (strcmp(token, "func") == 0) { if(lastline != -1) printf("\n"); break; } if (lastline != lineno) { if (lastline == lineno-1) printf("\n"); else printf("\n#line %d \"%s\"\n", lineno, file); lastline = lineno; } printf("%s ", token); } *name = read_token_no_eof(); token = read_token(); if (token == NULL || strcmp(token, "(") != 0) { fprintf(stderr, "%s:%u: expected \"(\"\n", file, lineno); exit(1); } *params = read_params(paramwid); token = read_token(); if (token == NULL || strcmp(token, "(") != 0) *rets = NULL; else { *rets = read_params(NULL); token = read_token(); } if (token == NULL || strcmp(token, "{") != 0) { fprintf(stderr, "%s:%u: expected \"{\"\n", file, lineno); exit(1); } return 1; }
/* * Read a type in Go syntax and return a type in C syntax. We only * permit basic types and pointers. */ static char * read_type(void) { char *p, *op, *q; int pointer_count; unsigned int len; p = read_token_no_eof(); if (*p != '*') { /* Convert the Go type "int" to the C type "intgo", and similarly for "uint". */ if (strcmp(p, "int") == 0) return xstrdup("intgo"); else if (strcmp(p, "uint") == 0) return xstrdup("uintgo"); return p; } op = p; pointer_count = 0; while (*p == '*') { ++pointer_count; ++p; } /* Convert the Go type "int" to the C type "intgo", and similarly for "uint". */ if (strcmp(p, "int") == 0) p = (char *) "intgo"; else if (strcmp(p, "uint") == 0) p = (char *) "uintgo"; len = strlen(p); q = xmalloc(len + pointer_count + 1); memcpy(q, p, len); while (pointer_count > 0) { q[len] = '*'; ++len; --pointer_count; } q[len] = '\0'; free(op); return q; }