1960 lines · 55.3 KB · C++
RawDownload
/*----------------------------------------------------------------------------  ChucK Concurrent, On-the-fly Audio Programming Language    Compiler and Virtual Machine   Copyright (c) 2004 Ge Wang and Perry R. Cook.  All rights reserved.    http://chuck.stanford.edu/    http://chuck.cs.princeton.edu/   This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.   This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.   You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  U.S.A.-----------------------------------------------------------------------------*/ //-----------------------------------------------------------------------------// file: ulib_machine.cpp// desc: class library for 'Machine'//// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)// date: Spring 2004//-----------------------------------------------------------------------------#include "ulib_doc.h"#include "chuck.h"#include "chuck_type.h"#include "chuck_vm.h"#include "chuck_instr.h"#include "chuck_compile.h"#include "chuck_errmsg.h"#include "util_string.h" #include <string>#include <sstream>#include <fstream>#include <algorithm>using namespace std; // 1.5.0.0 ((ge, spencer) | addedCK_DLL_CTOR( CKDoc_ctor );CK_DLL_DTOR( CKDoc_dtor );CK_DLL_MFUN( CKDoc_addGroup_str );CK_DLL_MFUN( CKDoc_addGroup_type );CK_DLL_MFUN( CKDoc_numGroups );CK_DLL_MFUN( CKDoc_clearGroup );CK_DLL_CTRL( CKDoc_examplesRoot_set );CK_DLL_CGET( CKDoc_examplesRoot_get );CK_DLL_CTRL( CKDoc_outputFormat_set );CK_DLL_CGET( CKDoc_outputFormat_get );CK_DLL_MFUN( CKDoc_genIndex );CK_DLL_MFUN( CKDoc_genCSS );CK_DLL_MFUN( CKDoc_genGroups );CK_DLL_MFUN( CKDoc_genType_type );CK_DLL_MFUN( CKDoc_genType_str );CK_DLL_MFUN( CKDoc_outputToDir );// offsetstatic t_CKUINT CKDoc_offset_data = 0; // static initializationt_CKINT const CKDoc::FORMAT_NONE = 0;t_CKINT const CKDoc::FORMAT_HTML = 1;t_CKINT const CKDoc::FORMAT_TEXT = 2;t_CKINT const CKDoc::FORMAT_MARKDOWN = 3;t_CKINT const CKDoc::FORMAT_JSON = 4;    //-----------------------------------------------------------------------------// name: ckdoc_query()// desc: add class for ckdoc documentation generator | 1.5.0.0 (ge, spencer, terry)//-----------------------------------------------------------------------------DLL_QUERY ckdoc_query( Chuck_DL_Query * QUERY ){    // get environment reference    Chuck_Env * env = QUERY->env();    // set module name    QUERY->setname( QUERY, "CKDoc" );     // function    Chuck_DL_Func * func = NULL;    // documentation string    std::string doc;     //---------------------------------------------------------------------    // init as class    // 1.5.0.0 added by spencer and ge    //---------------------------------------------------------------------    // doc string    doc = "A ChucK documentation generator. Based on Spencer Salazar's ckdoc utility.";     // begin class definition    if( !type_engine_import_class_begin( env, "CKDoc", "Object", env->global(), CKDoc_ctor, CKDoc_dtor, doc.c_str() ) )        return FALSE;     // data offset    CKDoc_offset_data = type_engine_import_mvar( env, "int", "@CKDoc_data", FALSE );    if( CKDoc_offset_data == CK_INVALID_OFFSET ) goto error;     // const static variables, for format selection, e.g., with CKDoc.HTML or CKDoc.TEXT    if( !type_engine_import_svar( env, "int", "NONE", TRUE, (t_CKUINT)&CKDoc::FORMAT_NONE, "no output format." ) ) goto error;    if( !type_engine_import_svar( env, "int", "HTML", TRUE, (t_CKUINT)&CKDoc::FORMAT_HTML, "output HTML format." ) ) goto error;    if( !type_engine_import_svar( env, "int", "TEXT", TRUE, (t_CKUINT)&CKDoc::FORMAT_TEXT, "output TEXT format (not implemented)." ) ) goto error;    if( !type_engine_import_svar( env, "int", "MARKDOWN", TRUE, (t_CKUINT)&CKDoc::FORMAT_MARKDOWN, "output MARKDOWN format (not implemented)." ) ) goto error;    if( !type_engine_import_svar( env, "int", "JSON", TRUE, (t_CKUINT)&CKDoc::FORMAT_JSON, "output JSON format (not implemented)." ) ) goto error;     // addGroup (by types)    func = make_new_mfun( "void", "addGroup", CKDoc_addGroup_type );    func->add_arg( "Type[]", "types" );    func->add_arg( "string", "name" );    func->add_arg( "string", "shortName" );    func->add_arg( "string", "description" );    func->doc = "Add a group of types to be documented, including group 'name', a 'shortName' to be used for any files, and a group 'description'.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // addGroup (by names)    func = make_new_mfun( "void", "addGroup", CKDoc_addGroup_str );    func->add_arg( "string[]", "typeNames" );    func->add_arg( "string", "name" );    func->add_arg( "string", "shortName" );    func->add_arg( "string", "description" );    func->doc = "Add a group of types (by type name) to be documented, including group 'name', a 'shortName' to be used for any files, and a group 'description'.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // numGroups    func = make_new_mfun( "int", "numGroups", CKDoc_numGroups );    func->doc = "Get the number of groups added.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // clear    func = make_new_mfun( "void", "clear", CKDoc_clearGroup );    func->doc = "Clear all added groups.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // examplesRoot    func = make_new_mfun( "string", "examplesRoot", CKDoc_examplesRoot_set );    func->add_arg( "string", "path" );    func->doc = "Set the examples directory root path; returns what was set.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // examplesRoot    func = make_new_mfun( "string", "examplesRoot", CKDoc_examplesRoot_get );    func->doc = "Get the current examples directory root path.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // outputFormat    func = make_new_mfun( "int", "outputFormat", CKDoc_outputFormat_set );    func->add_arg( "int", "which" );    func->doc = "Set which output format to use; see CKDoc.HTML, CKDoc.TEXT, CKDoc.MARKDOWN, CKDoc.JSON.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // CKDoc_outputFormat_set    func = make_new_mfun( "int", "outputFormat", CKDoc_outputFormat_get );    func->doc = "Set which output format is selected; see CKDoc.HTML, CKDoc.TEXT, CKDoc.MARKDOWN, CKDoc.JSON.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // genIndex    func = make_new_mfun( "string", "genIndex", CKDoc_genIndex );    func->add_arg( "string", "indexTitle" );    func->doc = "Generate top-level index; return as string.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // genCSS    func = make_new_mfun( "string", "genCSS", CKDoc_genCSS );    func->doc = "Generate CSS; return as string.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // genGroups    func = make_new_mfun( "void", "genGroups", CKDoc_genGroups );    func->add_arg( "string[]", "results" );    func->doc = "Generate documentation for all added groups, return each in a separate entry";    if( !type_engine_import_mfun( env, func ) ) goto error;     // genType    func = make_new_mfun( "string", "genType", CKDoc_genType_type );    func->add_arg( "Type", "type" );    func->doc = "Generate documentation for a single Type.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // genType    func = make_new_mfun( "string", "genType", CKDoc_genType_str );    func->add_arg( "string", "typeName" );    func->doc = "Generate documentation for a single Type (by name).";    if( !type_engine_import_mfun( env, func ) ) goto error;     // outputToDir    func = make_new_mfun( "int", "outputToDir", CKDoc_outputToDir );    func->add_arg( "string", "path" );    func->add_arg( "string", "indexTitle" );    func->doc = "Generate everything as files into the output directory.";    if( !type_engine_import_mfun( env, func ) ) goto error;     // end the class import    type_engine_import_class_end( env );     return true; error:     return false;}    //-----------------------------------------------------------------------------// name: struct CKDocGroup | 1.5.0.0 (ge, spencer) added// desc: structure for a doc group e.g., "UGens"//-----------------------------------------------------------------------------struct CKDocGroup{    // types in the group    vector<Chuck_Type *> types;    // name of the group    string name;    // short name of the group (used for filenames and such)    string shortName;    // description of the group    string desc;};    //-----------------------------------------------------------------------------// name: type2url()// desc: convert type name to URL, using groups to detemine the file for each//-----------------------------------------------------------------------------string type2url( const string & type, const vector<CKDocGroup *> & groups ){    // search    for( t_CKINT i = 0; i < groups.size(); i++ )    {        for( t_CKINT j = 0; j < groups[i]->types.size(); j++ )        {            // check            if( groups[i]->types[j] == NULL ) continue;            // compare            if( type == groups[i]->types[j]->name )            {                // file + location within file: basically: 'group.html#type'                return groups[i]->shortName + ".html#" + type;            }        }    }     // TODO: make a list of default classes on chuck website to link to    // return "[type2url NOT IMPLEMENTED]";    return "";}     //-----------------------------------------------------------------------------// name: class CKDocHTMLOutput | 1.5.0.0 (ge, spencer) added// desc: HTML output (based on Spencer's ckdoc)//-----------------------------------------------------------------------------class CKDocHTMLOutput : public CKDocOutput{private:    Chuck_Func * m_func;    std::string m_title;    Chuck_VM * m_vm_ref;    Chuck_Env * m_env_ref; public:    CKDocHTMLOutput( Chuck_VM * vm )        : m_vm_ref(vm), m_func(NULL)    {        // get the env        m_env_ref = vm != NULL ? vm->env() : NULL;    }    // file extension    virtual string fileExtension() const { return ".html"; }    // render HTML index    virtual string renderIndex( const string & indexTitle, const vector<CKDocGroup *> & groups ); public:    void begin( const string & title )    {        // trim        m_title = trim(title);        // check length        if( m_title.length() == 0 ) m_title = "&nbsp;";        // string to return         m_outputStr += "<html>\n";        m_outputStr += "<link rel=\"stylesheet\" type=\"text/css\" href=\"ckdoc.css\" />\n";        m_outputStr += "<link rel=\"stylesheet\" type=\"text/css\" href=\"class.css\" />\n";        m_outputStr += "<title>" + m_title + "</title>\n";        m_outputStr += "<body>\n";    }     void heading()    {        m_outputStr += "<a name=\"top\"/>\n";        m_outputStr += "<div id=\"title\">\n";        m_outputStr += "<div class=\"titleL\">\n";        m_outputStr += "<div style=\"display: flex; align-items: center;\">";        m_outputStr += "<div class=\"inline titlelogo\"><a href=\"https://chuck.stanford.edu/\" target=\"_blank\"><img src=\"https://chuck.stanford.edu/doc/images/chuck-logo2023w.png\" /> </div>";        m_outputStr += "<div class=\"inline\"><h1><a href=\"./\">ChucK Class Library Reference</a></h1></div>\n";        m_outputStr += "<div class=\"inline gray\"><h1>&nbsp;&nbsp;<span style=\"color:black\">/</span>&nbsp;&nbsp;" + m_title + "</h1></div>\n";        m_outputStr += "</div>\n";        m_outputStr += "</div>\n";        m_outputStr += "</div>\n"; // #title    }     void end()    {        m_outputStr += "</html>\n";    }     void title(const std::string &_title)    {    }     void begin_body()    {        m_outputStr += "<div id=\"body\">\n";    }     void end_body()    {        m_outputStr += "</div>\n"; // #body        m_outputStr += "</body>\n";    }     void begin_toc()    {        m_outputStr += "<div class=\"toc\"><a id=\"toc\"/>\n";    }     void toc_class(Chuck_Type * type)    {        m_outputStr += "<p class=\"toc_class\"><a href=\"#" + type->name                     + "\" class=\"" + css_class_for_type(m_env_ref, type)                     + "\">" + type->name + "</a></p>\n";    }     void end_toc()    {        m_outputStr += "</div>\n";    }     void begin_classes( CKDocGroup * group )    {        m_outputStr += "<div class=\"classes\">\n";        m_outputStr += "<p class=\"group_desc\">" + group->desc + "</p>\n";    }     void end_classes()    {        m_outputStr += "</div>\n";    }     void begin_class(Chuck_Type * type, const vector<CKDocGroup *> & groups )    {        m_outputStr += "<a name=\"" + type->name + "\" /><div class=\"class\">\n";        m_outputStr += "<h2 class=\"class_title\" name=\"" + type->name + "\">" + type->name + "</h2>\n";         // type heirarchy        Chuck_Type * parent = type->parent;        // check if there is a parent class        if( parent != NULL )        {            m_outputStr += "<h4>";            m_outputStr += "<span class=\"class_inherits\">inherits</span> ";            // m_outputStr += "<h4 class=\"class_hierarchy\">";        }        // iterate over parents        while( parent != NULL )        {            m_outputStr += ": <a href=\"" + type2url(parent->name, groups)                         + "\" class=\"" + css_class_for_type(m_env_ref, parent)                         + "\">" + parent->name + "</a> ",            // go up the inheritance chain            parent = parent->parent;        }        // end the tag        if( type->parent != NULL ) m_outputStr += "</h4>\n";         if(type->doc.size() > 0)        {            std::string doc = capitalize(type->doc);            m_outputStr += "<p class=\"class_description\">" + doc + "<p>\n";        }        else            m_outputStr += "<p class=\"empty_class_description\">No description available</p>\n";    }     void end_class()    {        m_outputStr += "<p class=\"top_link\">[ <a href=\"#top\">top</a> ]</p>\n";        m_outputStr += "</div>\n<hr />\n";    }     void begin_examples()    {        m_outputStr += "<h3 class=\"class_section_header\">examples</h3><div class=\"examples\"><ul>\n";    }     void end_examples()    {        m_outputStr += "</ul></div>\n";    }     void begin_static_member_vars()    {        m_outputStr += "<h3 class=\"class_section_header\">static member variables</h3>\n<div class=\"members\">\n";    }     void end_static_member_vars()    {        m_outputStr += "</div>\n";    }     void begin_member_vars()    {        m_outputStr += "<h3 class=\"class_section_header\">member variables</h3>\n<div class=\"members\">\n";    }     void end_member_vars()    {        m_outputStr += "</div>\n";    }     void begin_static_member_funcs()    {        m_outputStr += "<h3 class=\"class_section_header\">static member functions</h3>\n<div class=\"members\">\n";    }     void end_static_member_funcs()    {        m_outputStr += "</div>\n";    }     void begin_member_funcs()    {        m_outputStr += "<h3 class=\"class_section_header\">member functions</h3>\n<div class=\"members\">\n";    }     void end_member_funcs()    {        m_outputStr += "</div>\n";    }     void example(const std::string &name, const std::string &url)    {        m_outputStr += "<li><a target=\"_blank\" href=\"" + url + "\">" + name + "</a></li>\n";    }     void static_member_var(Chuck_Value * var)    {        m_outputStr += "<div class=\"member\">\n<p class=\"member_declaration\"><span class=\""                     + css_class_for_type(m_env_ref, var->type) + "\">"                     + var->type->name;        // check array depth        if( var->type->array_depth )        {            m_outputStr += "</span>";            m_outputStr += "<span class=\"typename\">";            for(int i = 0; i < var->type->array_depth; i++)                m_outputStr += "[]";        }        m_outputStr += "</span> ";         // function name        m_outputStr += "<span class=\"membername\">" + var->name + "</span></p>";         if(var->doc.size() > 0)            m_outputStr += "<p class=\"member_description\">" + capitalize(var->doc) + "</p>\n";        else            m_outputStr += "<p class=\"empty_member_description\">No description available</p>\n";         m_outputStr += "</div>\n";    }     void member_var(Chuck_Value * var)    {        m_outputStr += "<div class=\"member\">\n<p class=\"member_declaration\"><span class=\""                     + css_class_for_type(m_env_ref, var->type) + "\">" + var->type->name;        // check array depth        if( var->type->array_depth )        {            m_outputStr += "</span>";            m_outputStr += "<span class=\"typename\">";            for(int i = 0; i < var->type->array_depth; i++)                m_outputStr += "[]";        }        m_outputStr += "</span> ";

Lines 1–500 of 1960.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t