| @@ -37,6 +37,7 @@ · 36 unmodified lines |
| 37 | 37 | #include "chuck_errmsg.h" |
| 38 | 38 | #include "chuck_lang.h" |
| 39 | 39 | #include "chuck_io.h" |
| 40 | +#include "chuck_symbol.h" |
| 40 | 41 | #include "util_string.h" |
| 41 | 42 | #include "ugen_xxx.h" |
| 42 | 43 | |
| @@ -6649,19 +6650,105 @@ const char * Chuck_Type::c_name() · 6606 unmodified lines |
| 6649 | 6650 | |
| 6650 | 6651 | //----------------------------------------------------------------------------- |
| 6651 | 6652 | // name: apropos() |
| 6652 | | −// desc: dump info to string |
| 6653 | +// desc: dump info to string; added 1.4.0.2 (ge) |
| 6654 | +// portions of this adapted from ckdoc -- thanks be to Spencer Salazar |
| 6653 | 6655 | //----------------------------------------------------------------------------- |
| 6654 | 6656 | void Chuck_Type::apropos( std::string & output ) |
| 6655 | 6657 | { |
| 6656 | 6658 | // reset |
| 6657 | 6659 | output = ""; |
| 6660 | + // line prefix |
| 6661 | + string PREFIX = ""; // [chuck]: "; |
| 6662 | + |
| 6663 | + //------------------------------------------------------------------------- |
| 6664 | + // top level info: name, inheritane, description |
| 6665 | + //------------------------------------------------------------------------- |
| 6666 | + string outputTop; |
| 6667 | + // generate string |
| 6668 | + apropos_top( outputTop, PREFIX ); |
| 6669 | + |
| 6670 | + //------------------------------------------------------------------------- |
| 6671 | + // functions |
| 6672 | + //------------------------------------------------------------------------- |
| 6673 | + string outputFuncs; |
| 6674 | + // generate string |
| 6675 | + apropos_funcs( outputFuncs, PREFIX, TRUE ); |
| 6676 | + |
| 6677 | + //------------------------------------------------------------------------- |
| 6678 | + // variables |
| 6679 | + //------------------------------------------------------------------------- |
| 6680 | + string outputVars; |
| 6681 | + // generate string |
| 6682 | + // apropos_vars( outputVars, PREFIX, TRUE ); |
| 6683 | + |
| 6684 | + //------------------------------------------------------------------------- |
| 6685 | + // examples |
| 6686 | + //------------------------------------------------------------------------- |
| 6687 | + string outputExamples; |
| 6688 | + // generate string |
| 6689 | + // apropos_examples( outputExamples, PREFIX ); |
| 6690 | + |
| 6691 | + // done |
| 6692 | + output = outputTop + outputFuncs + outputVars + outputExamples; |
| 6693 | +} |
| 6694 | + |
| 6695 | + |
| 6696 | + |
| 6697 | + |
| 6698 | +//----------------------------------------------------------------------------- |
| 6699 | +// name: apropos() |
| 6700 | +// desc: dump info to console |
| 6701 | +//----------------------------------------------------------------------------- |
| 6702 | +void Chuck_Type::apropos() |
| 6703 | +{ |
| 6704 | + // the info |
| 6705 | + string output; |
| 6706 | + // get it |
| 6707 | + this->apropos( output ); |
| 6708 | + // print it |
| 6709 | + CK_STDCERR << output << CK_STDENDL; |
| 6710 | +} |
| 6711 | + |
| 6712 | + |
| 6713 | + |
| 6714 | + |
| 6715 | +// comparer |
| 6716 | +static bool comp_func( Chuck_Func * a, Chuck_Func * b ) |
| 6717 | +{ return a->name < b->name; } |
| 6718 | + |
| 6719 | +// comparer |
| 6720 | +static bool comp_value( Chuck_Value * a, Chuck_Value * b ) |
| 6721 | +{ return a->name < b->name; } |
| 6722 | + |
| 6723 | +// capitalize first character |
| 6724 | +static string capitalize( const string & s ) |
| 6725 | +{ |
| 6726 | + // copy |
| 6727 | + string retval = s; |
| 6728 | + // if not empty and first character is a lower-case letter |
| 6729 | + if( retval.length() > 0 && retval[0] >= 'a' && retval[0] <= 'z' ) |
| 6730 | + retval[0] -= 32; |
| 6731 | + // done |
| 6732 | + return retval; |
| 6733 | +} |
| 6734 | + |
| 6735 | + |
| 6736 | + |
| 6737 | + |
| 6738 | +//----------------------------------------------------------------------------- |
| 6739 | +// name: apropos_top() |
| 6740 | +// desc: dump top level info; added 1.4.0.2 (ge) |
| 6741 | +//----------------------------------------------------------------------------- |
| 6742 | +void Chuck_Type::apropos_top( std::string & output, const std::string & PREFIX ) |
| 6743 | +{ |
| 6658 | 6744 | // make a string output stream |
| 6659 | 6745 | ostringstream sout; |
| 6660 | 6746 | // type |
| 6661 | 6747 | Chuck_Type * type = this; |
| 6662 | | − // line prefix |
| 6663 | | − string PREFIX = ""; // [chuck]: "; |
| 6664 | 6748 | |
| 6749 | + //------------------------------------------------------------------------- |
| 6750 | + // top level info: name, inheritane, description |
| 6751 | + //------------------------------------------------------------------------- |
| 6665 | 6752 | // delimiter |
| 6666 | 6753 | sout << PREFIX; |
| 6667 | 6754 | for( int i = 0; i < str().length(); i++ ) sout << "-"; |
| @@ -6672,10 +6759,13 @@ void Chuck_Type::apropos( std::string & output ) · 4 unmodified lines |
| 6672 | 6759 | sout << PREFIX; |
| 6673 | 6760 | for( int i = 0; i < str().length(); i++ ) sout << "-"; |
| 6674 | 6761 | sout << endl; |
| 6762 | + // description |
| 6763 | + if( this->doc != "" ) |
| 6764 | + sout << PREFIX << " |- " << capitalize(this->doc) << "" << endl; |
| 6675 | 6765 | // inheritance |
| 6676 | 6766 | if( type->parent != NULL ) |
| 6677 | 6767 | { |
| 6678 | | − sout << PREFIX << " |- inherits"; |
| 6768 | + sout << PREFIX << " |- inheritance: " << str(); |
| 6679 | 6769 | while( type->parent != NULL ) |
| 6680 | 6770 | { |
| 6681 | 6771 | // move up |
| @@ -6687,37 +6777,11 @@ void Chuck_Type::apropos( std::string & output ) · 5 unmodified lines |
| 6687 | 6777 | // set back to this |
| 6688 | 6778 | type = this; |
| 6689 | 6779 | } |
| 6690 | | − // description |
| 6691 | | − if( this->doc != "" ) |
| 6692 | | − sout << PREFIX << " |- description: " << this->doc << "" << endl; |
| 6693 | | − |
| 6694 | | −// // storage for functions in type |
| 6695 | | −// vector<Chuck_Func *> funcs; |
| 6696 | | −// // get functions from type info |
| 6697 | | −// type->parent->parent->info->get_funcs( funcs ); |
| 6698 | | −// // print functions |
| 6699 | | −// for( t_CKUINT i = 0; i < funcs.size(); i++ ) |
| 6700 | | −// { |
| 6701 | | −// // sout << funcs[i]->base_name << endl; |
| 6702 | | −// } |
| 6703 | | − |
| 6704 | | − // // storage for values in type |
| 6705 | | − // vector<Chuck_Value *> values; |
| 6706 | | − // // get values from type info |
| 6707 | | − // type->parent->parent->parent->info->get_values( values ); |
| 6708 | | − // // print values |
| 6709 | | − // for( t_CKUINT i = 0; i < values.size(); i++ ) |
| 6710 | | − // { |
| 6711 | | − // CK_STDCERR << values[i]->name << CK_STDENDL; |
| 6712 | | − // } |
| 6713 | | − // |
| 6714 | | − // CK_STDCERR << funcs.size() << " " << values.size() << CK_STDENDL; |
| 6715 | | − |
| 6780 | + // delimiter |
| 6716 | 6781 | sout << PREFIX; |
| 6717 | 6782 | for( int i = 0; i < str().length(); i++ ) sout << "-"; |
| 6718 | 6783 | sout << endl; |
| 6719 | | − |
| 6720 | | − // done |
| 6784 | + // store |
| 6721 | 6785 | output = sout.str(); |
| 6722 | 6786 | } |
| 6723 | 6787 | |
| @@ -6725,15 +6789,173 @@ void Chuck_Type::apropos( std::string & output ) · 1 unmodified line |
| 6725 | 6789 | |
| 6726 | 6790 | |
| 6727 | 6791 | //----------------------------------------------------------------------------- |
| 6728 | | −// name: apropos() |
| 6729 | | −// desc: dump info to console |
| 6792 | +// name: apropos_func_arg() |
| 6793 | +// desc: helper function for outputing function arguments |
| 6730 | 6794 | //----------------------------------------------------------------------------- |
| 6731 | | −void Chuck_Type::apropos() |
| 6795 | +void apropos_func_arg( std::ostringstream & sout, a_Arg_List arg ) |
| 6732 | 6796 | { |
| 6733 | | − // the info |
| 6734 | | − string output; |
| 6735 | | − // get it |
| 6736 | | − this->apropos( output ); |
| 6737 | | − // print it |
| 6738 | | − CK_STDCERR << output << CK_STDENDL; |
| 6797 | + // argument type |
| 6798 | + sout << arg->type->name.c_str(); |
| 6799 | + // is type an array? |
| 6800 | + if( arg->type->array_depth ) |
| 6801 | + { |
| 6802 | + for( int i = 0; i < arg->type->array_depth; i++ ) |
| 6803 | + sout << "[]"; |
| 6804 | + } |
| 6805 | + // space |
| 6806 | + sout << " "; |
| 6807 | + // argument name |
| 6808 | + sout << S_name(arg->var_decl->xid); |
| 6809 | + // print comma, if there are more arguments after this |
| 6810 | + if( arg->next != NULL ) |
| 6811 | + sout << ", "; |
| 6812 | +} |
| 6813 | + |
| 6814 | + |
| 6815 | + |
| 6816 | + |
| 6817 | +//----------------------------------------------------------------------------- |
| 6818 | +// name: apropos_func() |
| 6819 | +// desc: helper function for outputing function |
| 6820 | +//----------------------------------------------------------------------------- |
| 6821 | +void apropos_func( std::ostringstream & sout, Chuck_Func * func, const std::string & PREFIX ) |
| 6822 | +{ |
| 6823 | + // output return type |
| 6824 | + sout << func->def->ret_type->c_name(); |
| 6825 | + // if return type is an array |
| 6826 | + if( func->def->ret_type->array_depth ) |
| 6827 | + { |
| 6828 | + // output "[]" for each dimension of the array |
| 6829 | + for( int i = 0; i < func->def->ret_type->array_depth; i++ ) |
| 6830 | + sout << "[]"; |
| 6831 | + } |
| 6832 | + // space |
| 6833 | + sout << " "; |
| 6834 | + // output function name |
| 6835 | + sout << S_name(func->def->name); |
| 6836 | + // open paren |
| 6837 | + sout << "("; |
| 6838 | + // extra space, if we have args |
| 6839 | + if( func->def->arg_list != NULL ) sout << " "; |
| 6840 | + |
| 6841 | + // argument list |
| 6842 | + a_Arg_List args = func->def->arg_list; |
| 6843 | + while( args != NULL ) |
| 6844 | + { |
| 6845 | + // output arg |
| 6846 | + apropos_func_arg( sout, args ); |
| 6847 | + // move to next |
| 6848 | + args = args->next; |
| 6849 | + } |
| 6850 | + |
| 6851 | + // extra space, if we are args |
| 6852 | + if( func->def->arg_list != NULL ) sout << " "; |
| 6853 | + |
| 6854 | + // close paren |
| 6855 | + sout << ");" << endl; |
| 6856 | + // output doc |
| 6857 | + sout << PREFIX << " " << capitalize(func->doc) << endl; |
| 6858 | +} |
| 6859 | + |
| 6860 | + |
| 6861 | + |
| 6862 | + |
| 6863 | +//----------------------------------------------------------------------------- |
| 6864 | +// name: apropos_funcs() |
| 6865 | +// desc: dump info about funcs; added 1.4.0.2 (ge) |
| 6866 | +//----------------------------------------------------------------------------- |
| 6867 | +void Chuck_Type::apropos_funcs( std::string & output, const std::string & PREFIX, t_CKBOOL includeParents ) |
| 6868 | +{ |
| 6869 | + // make a string output stream |
| 6870 | + ostringstream sout; |
| 6871 | + |
| 6872 | + // check type info |
| 6873 | + if( this->info ) |
| 6874 | + { |
| 6875 | + // retrieve functions in this type |
| 6876 | + vector<Chuck_Func *> funcs; |
| 6877 | + this->info->get_funcs(funcs); |
| 6878 | + // retrieve variables in this type |
| 6879 | + vector<Chuck_Value *> vars; |
| 6880 | + this->info->get_values(vars); |
| 6881 | + |
| 6882 | + // member functions |
| 6883 | + vector<Chuck_Func *> mfuncs; |
| 6884 | + // static functions |
| 6885 | + vector<Chuck_Func *> sfuncs; |
| 6886 | + // member variables |
| 6887 | + vector<Chuck_Value *> mvars; |
| 6888 | + // static variables |
| 6889 | + vector<Chuck_Value *> svars; |
| 6890 | + // counter by name |
| 6891 | + map<string, int> func_names; |
| 6892 | + |
| 6893 | + // iterate over retrieved functions |
| 6894 | + for( vector<Chuck_Func *>::iterator f = funcs.begin(); f != funcs.end(); f++ ) |
| 6895 | + { |
| 6896 | + // get pointer to chuck func |
| 6897 | + Chuck_Func * func = *f; |
| 6898 | + // check for NULL |
| 6899 | + if( func == NULL ) continue; |
| 6900 | + // see if name appeared before |
| 6901 | + if( func_names.count(func->name) ) |
| 6902 | + { |
| 6903 | + // increment count associated with name |
| 6904 | + func_names[func->name]++; |
| 6905 | + // done for now |
| 6906 | + continue; |
| 6907 | + } |
| 6908 | + |
| 6909 | + // create entry for name |
| 6910 | + func_names[func->name] = 1; |
| 6911 | + |
| 6912 | + // check for static declaration |
| 6913 | + if( func->def->static_decl == ae_key_static ) { |
| 6914 | + // append to static funcs list |
| 6915 | + sfuncs.push_back(func); |
| 6916 | + } else { |
| 6917 | + // append to static funcs list |
| 6918 | + mfuncs.push_back(func); |
| 6919 | + } |
| 6920 | + } |
| 6921 | + |
| 6922 | + // sort |
| 6923 | + sort( mfuncs.begin(), mfuncs.end(), comp_func ); |
| 6924 | + sort( sfuncs.begin(), sfuncs.end(), comp_func ); |
| 6925 | + |
| 6926 | + // one or more static functions? |
| 6927 | + if( mfuncs.size() ) |
| 6928 | + { |
| 6929 | + // iterate over static functions |
| 6930 | + for( vector<Chuck_Func *>::iterator f = mfuncs.begin(); f != mfuncs.end(); f++ ) |
| 6931 | + { |
| 6932 | + // pointer to chuck func |
| 6933 | + Chuck_Func * func = *f; |
| 6934 | + // print line prefix, if any |
| 6935 | + sout << PREFIX; |
| 6936 | + // output function content |
| 6937 | + apropos_func( sout, func, PREFIX ); |
| 6938 | + } |
| 6939 | + } |
| 6940 | + |
| 6941 | + // one or more static functions? |
| 6942 | + if( sfuncs.size() ) |
| 6943 | + { |
| 6944 | + // iterate over static functions |
| 6945 | + for( vector<Chuck_Func *>::iterator f = sfuncs.begin(); f != sfuncs.end(); f++ ) |
| 6946 | + { |
| 6947 | + // pointer to chuck func |
| 6948 | + Chuck_Func * func = *f; |
| 6949 | + // print line prefix, if any |
| 6950 | + sout << PREFIX; |
| 6951 | + // print static |
| 6952 | + sout << "static "; |
| 6953 | + // output function content |
| 6954 | + apropos_func( sout, func, PREFIX ); |
| 6955 | + } |
| 6956 | + } |
| 6957 | + } |
| 6958 | + |
| 6959 | + // output to string |
| 6960 | + output = sout.str(); |
| 6739 | 6961 | } |