⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intgen.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 2 页
字号:
/* intgen.c -- an interface generator for xlisp *//* (c) Copyright Carnegie Mellon University 1991 * For a statement of limited permission to use, see Permission.doc * * HISTORY * *  5-Jul-95	Roger Dannenberg *	strip directory prefixes from files before writing include statements * 24-Oct-88	Roger Dannenberg at CMU *	Changed so that if C routine returns void and has result parameters, *	then result parameters are returned by the lisp subr as well as *	assigned to *RSLT*. * * 13-Apr-88	Roger Dannenberg at CMU *	Modified for xlisp version 2.0 * * 22-Dec-87    Roger Dannenberg at NeXT *	Added FILE type. * * 21-May-87	Dale Amon at CMU CSD *	Included use of NODE *s_true under SCORE_EDITOR conditional. Standard *	xlisp code use NODE *true instead. * * 13-May-87	Dale Amon at CMU CSD *	Added conditional compilation switch SCORE_EDITOR so that this *	program will work with both standard XLISP sources and with Roger's *	(ahem) modified version. Also put in error checking for case where *	user does not specifiy an output file so program will exit instead *	of coredump. *//* Summary and Design: (NOTE THAT AN INTGEN MANUAL IS AVAILABLE) *    The first command line argument gives the name of * the .c file to generate.  All following arguments are * .h files to read and use as interface specifications. * *    The main program opens the output file, calls * write_prelude, and then process_file for each input * file.  Then call write_postlude and close the file. * *    process_file opens an input file and reads each line * into current_line. *    if the first characters of the file are "ih", then * the rest of the file is processed as normal, except the * .h extension of the file is replaced by .ih before the * filename is written into an include statement in the  * output file.  This is done to handle ".ih" files generated * by the Andrew Toolkit Class processor. *    In any case, the first line of EVERY .h file is discarded. * If #define is found, save the following identifier as *    macro_name. * If "LISP:" is found, then see if it is preceded by one * or two identifiers and an open paren. *    If yes, call routine_call, *    else call macro_call. * *    routine_call gets the first one or two identifiers off the * line into type_name and routine_name.  If there is just one id, * assign it to routine_name and make type_name = "void".  * If the routine_name starts with *, remove the * from  * routine_name and append "*" to type_name. * Call write_interface with type_name, routine_name, and location * of parameter type description after "LISP:". * *    macro_call gets a type_name from the input line after * "LISP:". * Then call write_interface with type_name, macro_name, and * location of parameter type description. * *    lisp function names are saved in a table, and an * initialization routine is written to install the new * SUBRs into the xlisp symbol table, as well as to lookup * RSLT_sym, the atom on which results are placed * * *//* Turn on special handling for Roger's Score Editor if the following #define *    is uncommented: *//* #define SCORE_EDITOR *//* Turn on special handling for Chris's Sound Editor if the following #define *    is uncommented: *//* #define SOUND_EDITOR *//* Turn on special handling for Nyquist if the following #define *    is uncommented: */#define NYQUIST/* atom 't is named s_true if this is defined, o.w. named true: */#define S_TRUE 1/* Turn on special handling for CMU MIDI Toolkit seq_type: */#define SEQ_TYPE#define errfile stdout#define ident_max 100#define line_max 200#define subr_max 500/* prefix for include files not to be included in interface module */#define no_include_prefix '~'#define false 0#define true 1#include "switches.h"#include "stdlib.h"#include "cext.h"#include <string.h>#ifndef booleantypedef int boolean;#endif#include "stdio.h"#include "ctype.h"#include "cmdline.h"#ifdef MACINTOSH#include "console.h"#endif#ifdef MACINTOSH#define FILESEP ':'#else#ifdef WINDOWS#define FILESEP '\\'#else#define FILESEP '/'#endif#endifstatic char *sindex();#define whitep(c) ((c) == ' ' || (c) == '\t')#define symbolp(c) (isalpha(c) || (c) == '*' || (c) == '_' || (c) == '-' ||\                    (c) == ':' || isdigit(c) || (c) == '^' || (c) == '*')/* c and Lisp parameters are encoded in the same table. * Field type_id is the string name of the type. * For c types (return types of C routines), code is 'C', *   convert gives the routine for making a lisp node from *   the c datum. *   listtype_or_special is "v" for types that should be *   returned as LISP NIL (e.g. "void"), "s" for types *   that when NULL should be returned as NIL, "r" *   for normal types, and "" to raise an error. *   ctype is not used and should be NULL. * For Lisp types (from parameter specs), code is 'L'. *   convert gives the routine that extracts a C value *   from a lisp node whose type is given by the field *   getarg_or_special. *   c_type is the type of the local C variable which is *   passed as a parameter to the C routine. *   initializer is the initial value for result only parameters * * End of table is marked by a NULL type_id. * * Location 0 is reserved to indicate errors. * Location 1 MUST BE type ANY * */#define any_index 1struct {    char *type_id;    char code;    char *convert;    char *getarg_or_special;    char *ctype;    char *makenode;    char *initializer;} type_table[] = {        {" ", ' ', NULL, NULL, NULL, NULL, NULL},        {"ANY", 'L', "", "", "LVAL", "", "NIL"},        {"ATOM", 'L', "", "xlgasymbol", "LVAL", "", "NIL"},        {"FILE", 'L', "getfile", "xlgastream", "FILE *", "cvfile", "NULL"},        {"FIXNUM", 'L', "getfixnum", "xlgafixnum", "long", "cvfixnum", "0"},        {"FIXNUM", 'L', "getfixnum", "xlgafixnum", "int", "cvfixnum", "0"},        {"FLOAT", 'L', "getflonum", "xlgaflonum", "float", "cvflonum", "0.0"},        {"FLONUM", 'L', "getflonum", "xlgaflonum", "double", "cvflonum", "0.0"},        {"ANYNUM", 'L', "testarg2", "xlgaanynum", "double", "cvflonum", "0.0"},        {"STRING", 'L', "getstring", "xlgastring", "unsigned char *", "cvstring", "NULL"},        {"BOOLEAN", 'L', "getboolean", "xlgetarg", "int", "cvboolean", "0"},        {"atom_type", 'C', "", "r", NULL, NULL, NULL},        {"LVAL", 'C', "", "r", NULL, NULL, "NIL"},#ifdef SOUND_EDITOR        /* Extensions for Sound Type: */        {"SOUND", 'L', "getsound", "xlgasound", "SoundPtr", "cvsound", "NULL"},        {"SoundPtr", 'C', "cvsound", "r", NULL, NULL, NULL},#endif#ifdef NYQUIST        {"SOUND", 'L', "getsound", "xlgasound", "sound_type", "cvsound", "NULL"},        {"sound_type", 'C', "cvsound", "r", NULL, NULL, NULL},#endif#ifdef SEQ_TYPE         {"SEQ", 'L', "getseq", "xlgaseq", "seq_type", "cvseq", "NULL"},        {"seq_type", 'C', "cvseq", "r", NULL, NULL, NULL}, /* look out! event_type is treated as void to eliminate * warning messages ... */        {"event_type", 'C', "", "v", NULL, NULL, NULL},#endif#ifdef SCORE_EDITOR        {"VALUE",  'L', "getval", "xlgaval", "value_type", "cvval", "NULL"},        {"value_type", 'C', "cvval", "r", NULL, NULL, NULL},        {"EVENT",  'L', "getevent", "xlgaevent", "event_type", "cvevent", "NULL"},        {"event_type", 'C', "cvevent", "r", NULL, NULL, NULL},        {"score_type", 'C', "cvevent", "r", NULL, NULL, NULL},#endif#ifdef DMA_EXTENSIONS /* begin DMA entries */         {"DEXT", 'L', "getdext", "xlgadext", "ext_type", "cvdext", "NULL"},         {"DEXT", 'C', "cvdext", "r", NULL, NULL, NULL},         {"SEXT", 'L', "getsext", "xlgasext", "ext_type", "cvsext", "NULL"},         {"SEXT", 'C', "cvsext", "r", NULL, NULL, NULL}, /* end DMA entries */#endif        {"int", 'C', "cvfixnum", "r", NULL, NULL, NULL},        {"long", 'C', "cvfixnum", "r", NULL, NULL, NULL},        {"boolean", 'C', "cvboolean", "r", NULL, NULL, NULL},        {"float", 'C', "cvflonum", "r", NULL, NULL, NULL},        {"double", 'C', "cvflonum", "r", NULL, NULL, NULL},        {"string", 'C', "cvstring", "s", NULL, NULL, NULL},        {"char*", 'C', "cvstring", "s", NULL, NULL, NULL},        {"char", 'C', "cvfixnum", "r", NULL, NULL, NULL},        {"string_type", 'C', "cvstring", "s", NULL, NULL, NULL},        {"FILE*", 'C', "cvfile", "s", NULL, NULL, NULL},        {"void", 'C', "", "v", NULL, NULL, NULL},/*eot*/	{NULL, ' ', NULL, NULL, NULL, NULL, NULL}};/* subr names get saved here: */char *subr_table[subr_max];int subr_table_x;#define get_c_special(i) type_table[(i)].getarg_or_special[0]#define get_c_conversion(i) type_table[(i)].convert#define get_lisp_extract(i) type_table[(i)].convert#define get_lisp_getarg(i) type_table[(i)].getarg_or_special#define get_lisp_ctype(i) type_table[(i)].ctype#define get_lisp_makenode(i) type_table[(i)].makenode#define get_lisp_initializer(i) type_table[(i)].initializerstatic void lisp_code();static int lookup();static void process_file();static void routine_call();static void write_interface();static void write_postlude();static void write_prelude();static void write_ptrfile();char source_file[ident_max];	/* source file */char current_line[4 * line_max];    /* current line in source file */char out_file[ident_max];	/* output file name */char ptr_file[ident_max];	/* ptr.h file name */char def_file[ident_max];	/* def.h file name */FILE *lispout = NULL;		/* output for lisp source code (if any) */#define EOS '\000'/* getarg -- get an identifier from a string *//**/int getarg(start, result, pos)    char *start;	/* where to start scanning */    char *result;	/* where to put the identifier */    char **pos;		/* ptr to char after identifier in source */{    *result = EOS;    while (whitep(*start) && *start != EOS) start++;    if (*start == EOS) return false;    if (!symbolp(*start)) return false;    while (symbolp(*start) && *start != EOS) {        *result = *start;        result++;        start++;    }    *result = EOS;    *pos = start;    return true;}/* error() -- print source file and line *//**/void error(){    fprintf(errfile, "\n%s: |%s|\n", source_file, current_line);}/* lisp_code -- write lisp code to file *//* * read from inp if necessary until close comment found */static void lisp_code(inp, s)  FILE *inp;  char *s;{    char lisp[line_max];    char *endcomment;    char *inputline;   /* for end of file detection */    if (lispout == NULL) {        char lisp_file_name[ident_max];        char *extension;        strcpy(lisp_file_name, out_file);        extension = sindex(lisp_file_name, ".c");        strcpy(extension, ".lsp"); /* overwrite .c with .lsp */        lispout = fopen(lisp_file_name, "w");        if (lispout == NULL) {            fprintf(stdout, "Error: couldn't open %s\n", lisp_file_name);            exit(1);        }        printf("writing %s ...\n", lisp_file_name);    }    strcpy(lisp, s);	/* don't modify s */    inputline = lisp;    while (inputline != NULL &&           (endcomment = sindex(lisp, "*/")) == NULL) {        fputs(lisp, lispout);        inputline = fgets(lisp, line_max, inp);    }    strcpy(endcomment, "\n\n");    fputs(lisp, lispout);}/* lookup -- find type data *//**/static int lookup(s, t)    char *s;    char t;{    int i = 1;    while (type_table[i].type_id != NULL) {        if (type_table[i].code == t &&            strcmp(type_table[i].type_id, s) == 0)            return i;        i++;    }    return 0;}/* macro_call -- generate xlisp interface for C routine *//**/void macro_call(in, out, curline, macro_name, arg_loc)    FILE *in;		/* input file */    FILE *out;		/* output file */    char *curline;	/* input line */    char *macro_name;	/* name of the macro to call */    char *arg_loc;	/* location after "LISP:" */{    char type_name[ident_max];    if (!getarg(arg_loc, type_name, &arg_loc)) {        error();        fprintf(errfile, "no type given for macro.\n");    } else {        write_interface(in, out, type_name, macro_name, arg_loc, true);    }}/* main -- generate an xlisp to c interface file *//**/int main(argc, argv)    int argc;    char *argv[];{    char *s;    FILE *out;    FILE *ptrfile;    FILE *deffile;    int n;#ifdef MACINTOSH        argc = ccommand(&argv);#endif    for (n = 0; n < subr_max; n++)     {            subr_table[n] = (char *) malloc(ident_max);            subr_table[n][0] = EOS;    }    subr_table_x = 0;    cl_init(NULL, 0, NULL, 0, argv, argc);    if ((s = cl_arg(1)) != NULL) {             strcpy(out_file, s);           if (sindex(out_file, ".") == 0)                strcat(out_file, ".c");           else fprintf(stderr,                "1st command line argument should be a legal c identifier\n");           out = fopen(out_file, "w");           if (out == NULL) {               fprintf(stdout, "Error: couldn't open %s\n", out_file);               exit(1);           }             strcpy(ptr_file, s);           strcat(ptr_file, "ptrs.h");           ptrfile = fopen(ptr_file, "w");           if (ptrfile == NULL) {               fprintf(stdout, "Error: couldn't open %s\n", ptr_file);               exit(1);           }             strcpy(def_file, s);           strcat(def_file, "defs.h");           deffile = fopen(def_file, "w");           if (deffile == NULL) {               fprintf(stdout, "Error: couldn't open %s\n", def_file);               exit(1);           }    } else {           fprintf(stdout, "Error: no output file specified\n");           exit(1);    }    printf("writing %s ...\n", out_file);        write_prelude(out, out_file);    n = 2;    while ((s = cl_arg(n)) != NULL) {        printf("  %s\n", s);        process_file(s, out);        n++;    }    write_postlude(out);    fclose(out);    write_ptrfile(ptrfile, deffile);    fclose(ptrfile);    fclose(deffile);    if (lispout != NULL) fclose(lispout);    return 0;}static void process_file(fname, out)    char *fname;    FILE *out;{    FILE *in;    char *cp;    char *pos;    char incl_file[ident_max];	/* name of file to include */    char type_name[ident_max];		/* the type of the routine */    char routine_name[ident_max];	/* the name of the routine or macro */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -