mknfcts.c
来自「basic.c */ /**//* Project:NeuroBasic, b」· C语言 代码 · 共 539 行
C
539 行
/****************************************************************//* *//* Name: mknfcts.c *//* *//* Project: NeuroBasic, utility program *//* *//* Survey: Creates a C source file containing the global *//* neuro-function list and all corresponding *//* interface functions. Input files must contain *//* only neuro-function prototypes. *//* The output files are specified by the last two *//* arguments, all other arguments are considered *//* as input file names. *//* *//* Author: Urs Mueller *//* Electronics Laboratory, ETH Zuerich *//* Switzerland *//* *//* Created: July 20, 1994 *//* Modified: December 4, 1994 (mk) *//* *//****************************************************************/#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>/* macros *//**********/#define MINT_NAME "MINT"#define MFLOAT_NAME "MFLOAT"#define CHAR_NAME "char"#define VOID_NAME "void"#define LIST_MAX 512#define LINE_MAX 512#define TRUE 1#define FALSE 0/* type definitions *//********************/typedef enum{ RT_INVALID, RT_MINT, RT_MFLOAT, RT_VOID} ret_type_t;/* global variables *//********************/int error_flag;char *function_list[LIST_MAX];char *protos_list[LIST_MAX];long nfunctions = 0;static char *str_upper(char *str)/*=============================*/{ char *s; for (s = str; *s != 0; s++) *s = toupper(*s); return str;} /* end of str_upper() */static void add_to_string(char *string, char ch, int string_max)/*============================================================*/{ int i; i = 0; while (*string != 0) { i++; string++; } if (i < string_max-1) { *string++ = ch; *string = 0; } else string[-1] = -1; /* mark as false name */} /* end of add_to_string() */static ret_type_t check_ret_name(char *ret_name)/*============================================*/{ if (strcmp(ret_name, MINT_NAME) == 0) return RT_MINT; if (strcmp(ret_name, MFLOAT_NAME) == 0) return RT_MFLOAT; if (strcmp(ret_name, VOID_NAME) == 0) return RT_VOID; return RT_INVALID;} /* end of check_ret_name() */static int is_space(char *pch, FILE *fpt)/*=========================--==========*//* Like library function isspace() but skips comments of the C source code.*/{ char c2; if (isspace(*pch)) return TRUE; if (*pch != '/') return FALSE; *pch = fgetc(fpt); if (*pch != '*') /* is it a comment? */ { /* no */ ungetc(*pch, fpt); return FALSE; } else { /* skip the comment */ *pch = fgetc(fpt); do { c2 = *pch; *pch = fgetc(fpt); } while ((*pch != EOF) && (c2 != '*' || *pch != '/')); *pch = ' '; /* replace comment by a real space */ return TRUE; }} /* end of is_space() */static void scan_header(char *filename)/*===================================*//* Scans all input files and creates a list of function prototypes and corresponding function names.*/{#define RET_NAME_MAX 32 FILE *fpt; char ch, ret_name[RET_NAME_MAX], *prototype, *fname; ret_type_t ret_type; fpt = fopen(filename, "r"); if (fpt == NULL) { printf("ERROR of mknfcts: cannot read header file \"%s\".\n", filename); error_flag = EXIT_FAILURE; return; } ret_name[0] = 0; ch = fgetc(fpt); while (ch != EOF) { /*===== skipping white space and comments =====*/ while (is_space(&ch, fpt)) ch = fgetc(fpt); /*===== scanning a word =====*/ ret_type = check_ret_name(ret_name); ret_name[0] = 0; while (ch != EOF && ch != '(' && !is_space(&ch, fpt)) { add_to_string(ret_name, ch, RET_NAME_MAX); ch = fgetc(fpt); } /*===== is it a function prototype? =====*/ while (is_space(&ch, fpt)) ch = fgetc(fpt); if (ret_type == RT_INVALID || ch != '(') { /* not a prototype */ if (ch == '(') ch = fgetc(fpt); continue; } fname = malloc(strlen(ret_name) + 1); prototype = malloc(LINE_MAX); if (prototype == NULL || fname == 0) { printf("ERROR: Not enough memory to continue.\n"); if (fname != NULL) free(fname); if (prototype != NULL) free(prototype); error_flag = TRUE; break; } strcpy(fname, ret_name); prototype[0] = 0; switch (ret_type) { case RT_MINT: strcat(prototype, MINT_NAME); break; case RT_MFLOAT: strcat(prototype, MFLOAT_NAME); break; case RT_VOID: strcat(prototype, VOID_NAME); break; default: break; } /* end of switch () */ strcat(prototype, " "); strcat(prototype, fname); while (ch != EOF && ch != ')') { add_to_string(prototype, ch, LINE_MAX); ch = fgetc(fpt); } add_to_string(prototype, ch, LINE_MAX); ch = fgetc(fpt); add_to_string(prototype, ch, LINE_MAX); if (prototype[strlen(prototype)-2] == ')' && prototype[strlen(prototype)-1] == ';') { /* defenitely a prototype */ function_list[nfunctions] = fname; protos_list[nfunctions] = prototype; nfunctions++; } else { /* not a prototype */ free(fname); free(prototype); } } fclose(fpt);} /* end of scan_header() */static const char *skip_comment(const char *ps)/*===========================================*/{ if (ps[0] == '/' && ps[1] == '*') { ps += 2; while (ps[0] != 0 && (ps[0] != '*' || ps[1] != '/')) ps++; if (ps[0] != 0) ps++; } if (*ps != 0) ps++; return ps;} /* end of skip_comment() */static void compress_prototypes(void)/*=================================*//* Replaces the real prototype strings by a list of characters each representing the return type and all parameter types. v = void i = MINT f = MFLOAT a = variable number of arguments follow*/{ long fn; const char *ps; char *pd; int var_args; for (fn = 0; fn < nfunctions; fn++) { ps = pd = protos_list[fn]; if (strncmp(MINT_NAME, ps, strlen(MINT_NAME)) == 0) *pd++ = 'i'; /* MINT */ else if (strncmp(MFLOAT_NAME, ps, strlen(MFLOAT_NAME)) == 0) *pd++ = 'f'; /* MFLOAT */ else *pd++ = 'v'; /* void */ while (*ps != 0 && *ps != '(') ps = skip_comment(ps); if (*ps != 0) ps++; var_args = FALSE; while (*ps != 0) { while (*ps != 0 && (isspace(*ps) || *ps == '/')) ps = skip_comment(ps); if (strncmp(MINT_NAME, ps, strlen(MINT_NAME)) == 0) { *pd++ = 'i'; /* MINT */ ps += strlen(MINT_NAME); } else if (strncmp(MFLOAT_NAME, ps, strlen(MFLOAT_NAME)) == 0) { *pd++ = 'f'; /* MFLOAT */ ps += strlen(MFLOAT_NAME); } else if (strncmp(CHAR_NAME, ps, strlen(CHAR_NAME)) == 0) { /* char */ *pd++ = 'c'; ps += strlen(CHAR_NAME); } while (*ps != 0 && (isspace(*ps) || *ps == '/')) ps = skip_comment(ps); var_args = (*ps == '*'); while (*ps != 0 && *ps != ',') ps = skip_comment(ps); if (*ps != 0) ps++; } *pd = 0; /* terminate string */ if (var_args && strlen(protos_list[fn]) > 3) { pd[strlen(pd) - 2] = 'a'; pd[strlen(pd) - 1] = 'a'; } }} /* end of compress_prototypes() */static void release_memory(void)/*============================*/{ long i; for (i = 0; i < nfunctions; i++) free(function_list[i]); for (i = 0; i < nfunctions; i++) free(protos_list[i]);} /* end of release_memory() */static void write_file_header(FILE *fpt)/*====================================*/{ fprintf(fpt, "/*\n"); fprintf(fpt, " This file was created by mknfcts. "); fprintf(fpt, "Do not modify it!\n"); fprintf(fpt, "*/\n\n\n");} /* end of write_file_header() */static void write_fct_protos(char *filename)/*========================================*/{ FILE *ofpt; long fct; char name[FILENAME_MAX], *pc; pc = strrchr(filename, '/'); if (pc == NULL) pc = strrchr(filename, '\\'); if (pc == NULL) pc = filename; else pc++; strcpy(name, pc); pc = strrchr(name, '.'); if (pc != NULL) *pc = 0; str_upper(name); ofpt = fopen(filename, "w"); if (ofpt == NULL) { printf("ERROR of mkfcts: cannot open output file \"%s\".\n", filename); error_flag = EXIT_FAILURE; return; } write_file_header(ofpt); fprintf(ofpt, "\n\n#ifndef __%s__\n#define __%s__\n\n\n", name, name); fprintf(ofpt, "/* Prototypes of neuro-functions */\n"); fprintf(ofpt, "/*********************************/\n\n"); for (fct = 0; fct < nfunctions; fct++) fprintf(ofpt, "%s\n", protos_list[fct]); fprintf(ofpt, "\n\n"); fprintf(ofpt, "\n\n#endif /* __%s__ */\n", name); if (ferror(ofpt)) { printf("ERROR of mknfcts: Write error on \"%s\".\n", filename); error_flag = EXIT_FAILURE; } fclose(ofpt);} /* end fo write_fct_protos() */int main(int argc, char *argv[])/******************************/{ int arg, j; long nargs, fct; FILE *ofpt; if (argc < 4) { printf("Usage: mknfcts <input1> <input2> ... <.c-output> "); printf("<.h-output>\n"); return EXIT_FAILURE; } ofpt = fopen(argv[argc-2], "w"); if (ofpt == NULL) { printf("ERROR of mkfcts: cannot open output file \"%s\".\n", argv[argc-1]); return EXIT_FAILURE; } error_flag = EXIT_SUCCESS; write_file_header(ofpt); fprintf(ofpt, "#include <stdio.h>\n"); fprintf(ofpt, "#include <musiclib.h>\n\n"); fprintf(ofpt, "#include \"allnfcts.h\"\n"); fprintf(ofpt, "#include \"basic.h\"\n\n\n"); /*===== scan header files and create prototype list =====*/ for (arg = 1; arg < argc-2; arg++) scan_header(argv[arg]); /*===== write function prototypes =====*/ write_fct_protos(argv[argc-1]); /*===== make interface code for neuro-functions =====*/ compress_prototypes(); fprintf(ofpt, "/* interface functions */\n"); fprintf(ofpt, "/***********************/\n\n"); for (fct = 0; fct < nfunctions; fct++) { fprintf(ofpt, "static void if_%s(b_stack_t **pb_sp)\n{\n", function_list[fct]); if (strchr(protos_list[fct], 'c') != NULL) { fprintf(ofpt, " message_t msg;\n"); fprintf(ofpt, " MINT str_bufa[STR_BUF_MAX], *pa, i;\n"); fprintf(ofpt, " char *pb;\n"); } for (j = 0; j < strlen(protos_list[fct]) - 1; j++) { if (protos_list[fct][j+1] == 'c') { fprintf(ofpt, " char str_buf%db[STR_BUF_MAX];\n", j); } } if (protos_list[fct][strlen(protos_list[fct])-1] == 'a') { fprintf(ofpt, " MINT nargs;\n"); fprintf(ofpt, " nargs = ((*pb_sp)[-1].i - %ld);\n", strlen(protos_list[fct]) - 3); } fprintf(ofpt, " (*pb_sp) -= (*pb_sp)[-1].i;\n"); /* get strings from host */ for (j = 0; j < strlen(protos_list[fct]) - 1; j++) { if (protos_list[fct][j+1] == 'c') { fprintf(ofpt, " msg[0].i = C_SENDSTRING;\n"); fprintf(ofpt, " msg[1].i = (MINT)(*pb_sp)[%d].f;\n", j - 1); fprintf(ofpt, " Wr_to_host(msg, sizeof(msg), WR_ONE);\n"); fprintf(ofpt, " Rd_from_host(str_bufa, sizeof(str_bufa), RD_ALL);\n"); fprintf(ofpt, " pa = str_bufa;\n"); fprintf(ofpt, " pb = str_buf%db;\n", j); fprintf(ofpt, " for (i = 0; i < STR_BUF_MAX; i++)\n"); fprintf(ofpt, " *pb++ = *pa++;\n"); } } fprintf(ofpt, " "); if (protos_list[fct][0] != 'v') fprintf(ofpt, "(*pb_sp)[-1].f = "); if (protos_list[fct][0] == 'i') fprintf(ofpt, "(MFLOAT)"); fprintf(ofpt, "%s(", function_list[fct]); for (j = 0; j < strlen(protos_list[fct]) - 1; j++) { if (protos_list[fct][j+1] != 'a') { if (protos_list[fct][j+1] == 'c') { /* char */ fprintf(ofpt, "str_buf%db", j); } else { /* MINT or MFLOAT */ if (protos_list[fct][j+1] == 'i') fprintf(ofpt, "(MINT)"); fprintf(ofpt, "(*pb_sp)[%d].f", j - 1); } if (j < strlen(protos_list[fct]) - 2) fprintf(ofpt, ", "); } else { /* variable length argument list */ fprintf(ofpt, "nargs, (MFLOAT*)(*pb_sp + %ld)", strlen(protos_list[fct]) - 4); break; } } fprintf(ofpt, ");\n}\n\n"); } fprintf(ofpt, "\n"); /*===== make function-pointer array =====*/ fprintf(ofpt, "/* Array of function pointers */\n"); fprintf(ofpt, "/******************************/\n\n"); fprintf(ofpt, "FUNCTION_PTR_ARR_T function_ptr_arr[] =\n{\n"); for (fct = 0; fct < nfunctions; fct++) { nargs = strlen(protos_list[fct]) - 1; if (protos_list[fct][strlen(protos_list[fct])-1] == 'a') nargs = -(nargs - 2); fprintf(ofpt, " {\"%s\", if_%s, %ld},\n", function_list[fct], function_list[fct], nargs); } fprintf(ofpt, " {NULL, NULL, 0}\n};\n"); if (ferror(ofpt)) { printf("ERROR of mknfcts: Write error on \"%s\".\n", argv[argc-2]); error_flag = EXIT_FAILURE; } fclose(ofpt); release_memory(); return error_flag;} /* end of main() */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?