fl_function_type.cxx
来自「SRI international 发布的OAA框架软件」· CXX 代码 · 共 745 行 · 第 1/2 页
CXX
745 行
//
// "$Id: Fl_Function_Type.cxx,v 1.1.1.1 2003/06/03 22:25:40 agno Exp $"
//
// C function type code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2002 by Bill Spitzak and others.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems to "fltk-bugs@fltk.org".
//
#include <FL/Fl.H>
#include "Fl_Type.h"
#include <FL/fl_show_input.H>
#include "../src/flstring.h"
#include <stdio.h>
#include <stdlib.h>
extern int i18n_type;
extern const char* i18n_include;
extern const char* i18n_function;
extern const char* i18n_file;
extern const char* i18n_set;
extern char i18n_program[];
////////////////////////////////////////////////////////////////
// quick check of any C code for legality, returns an error message
static char buffer[128]; // for error messages
// check a quoted string ending in either " or ' or >:
const char *_q_check(const char * & c, int type) {
for (;;) switch (*c++) {
case '\0':
sprintf(buffer,"missing %c",type);
return buffer;
case '\\':
if (*c) c++;
break;
default:
if (*(c-1) == type) return 0;
}
}
// check normal code, match braces and parenthesis:
const char *_c_check(const char * & c, int type) {
const char *d;
for (;;) switch (*c++) {
case 0:
if (!type) return 0;
sprintf(buffer, "missing %c", type);
return buffer;
case '/':
// Skip comments as needed...
if (*c == '/') {
while (*c != '\n' && *c) c++;
} else if (*c == '*') {
c++;
while ((*c != '*' || c[1] != '/') && *c) c++;
if (*c == '*') c+=2;
else {
return "missing '*/'";
}
}
break;
case '#':
// treat cpp directives as a comment:
while (*c != '\n' && *c) c++;
break;
case '{':
if (type==')') goto UNEXPECTED;
d = _c_check(c,'}');
if (d) return d;
break;
case '(':
d = _c_check(c,')');
if (d) return d;
break;
case '\"':
d = _q_check(c,'\"');
if (d) return d;
break;
case '\'':
d = _q_check(c,'\'');
if (d) return d;
break;
case '}':
case ')':
UNEXPECTED:
if (type == *(c-1)) return 0;
sprintf(buffer, "unexpected %c", *(c-1));
return buffer;
}
}
const char *c_check(const char *c, int type) {
return _c_check(c,type);
}
////////////////////////////////////////////////////////////////
int Fl_Function_Type::is_public() const {return public_;}
Fl_Type *Fl_Function_Type::make() {
Fl_Type *p = Fl_Type::current;
while (p && !p->is_decl_block()) p = p->parent;
Fl_Function_Type *o = new Fl_Function_Type();
o->name("make_window()");
o->return_type = 0;
o->add(p);
o->factory = this;
o->public_ = 1;
o->cdecl_ = 0;
return o;
}
void Fl_Function_Type::write_properties() {
Fl_Type::write_properties();
if (!public_) write_string("private");
if (cdecl_) write_string("C");
if (return_type) {
write_string("return_type");
write_word(return_type);
}
}
void Fl_Function_Type::read_property(const char *c) {
if (!strcmp(c,"private")) {
public_ = 0;
} else if (!strcmp(c,"C")) {
cdecl_ = 1;
} else if (!strcmp(c,"return_type")) {
storestring(read_word(),return_type);
} else {
Fl_Type::read_property(c);
}
}
#include "function_panel.h"
#include <FL/fl_ask.H>
void Fl_Function_Type::open() {
if (!function_panel) make_function_panel();
f_return_type_input->static_value(return_type);
f_name_input->static_value(name());
f_public_button->value(public_);
f_c_button->value(cdecl_);
function_panel->show();
const char* message = 0;
for (;;) { // repeat as long as there are errors
if (message) fl_alert(message);
for (;;) {
Fl_Widget* w = Fl::readqueue();
if (w == f_panel_cancel) goto BREAK2;
else if (w == f_panel_ok) break;
else if (!w) Fl::wait();
}
const char*c = f_name_input->value();
while (isspace(*c)) c++;
message = c_check(c); if (message) continue;
const char *d = c;
for (; *d != '('; d++) if (isspace(*d) || !*d) break;
if (*c && *d != '(') {
message = "must be name(arguments), try again:"; continue;
}
c = f_return_type_input->value();
message = c_check(c); if (message) continue;
name(f_name_input->value());
storestring(c, return_type);
public_ = f_public_button->value();
cdecl_ = f_c_button->value();
break;
}
BREAK2:
function_panel->hide();
}
Fl_Function_Type Fl_Function_type;
extern const char* subclassname(Fl_Type*);
void Fl_Function_Type::write_code1() {
constructor=0;
havewidgets = 0;
Fl_Type *child;
for (child = next; child && child->level > level; child = child->next)
if (child->is_widget()) {
havewidgets = 1;
break;
}
write_c("\n");
if (ismain())
write_c("int main(int argc, char **argv) {\n");
else {
const char* rtype = return_type;
const char* star = "";
// from matt: let the user type "static " at the start of type
// in order to declare a static method;
int is_static = 0;
int is_virtual = 0;
if (rtype) {
if (!strcmp(rtype,"static")) {is_static = 1; rtype = 0;}
else if (!strncmp(rtype, "static ",7)) {is_static = 1; rtype += 7;}
if (!strcmp(rtype, "virtual")) {is_virtual = 1; rtype = 0;}
else if (!strncmp(rtype, "virtual ",8)) {is_virtual = 1; rtype += 8;}
}
if (!rtype) {
if (havewidgets) {
rtype = subclassname(child);
star = "*";
} else rtype = "void";
}
const char* k = class_name(0);
if (k) {
write_public(public_);
if (name()[0] == '~')
constructor = 1;
else {
size_t n = strlen(k);
if (!strncmp(name(), k, n) && name()[n] == '(') constructor = 1;
}
write_h(" ");
if (is_static) write_h("static ");
if (is_virtual) write_h("virtual ");
if (!constructor) {
write_h("%s%s ", rtype, star);
write_c("%s%s ", rtype, star);
}
// if this is a subclass, only write_h() the part before the ':'
char s[1024], *sptr = s;
char *nptr = (char *)name();
while (*nptr) {
if (*nptr == ':') {
if (nptr[1] != ':') break;
// Copy extra ":" for "class::member"...
*sptr++ = *nptr++;
}
*sptr++ = *nptr++;
}
*sptr = '\0';
write_h("%s;\n", s);
// skip all function default param. init in body:
int skips=0,skipc=0;
int nc=0,plevel=0;
for (sptr=s,nptr=(char*)name(); *nptr; nc++,nptr++) {
if (!skips && *nptr=='(') plevel++;
else if (!skips && *nptr==')') plevel--;
if ( *nptr=='"' && !(nc && *(nptr-1)=='\\') )
skips = skips ? 0 : 1;
else if(!skips && *nptr=='\'' && !(nc && *(nptr-1)=='\\'))
skipc = skipc ? 0 : 1;
if(!skips && !skipc && plevel==1 && *nptr =='=' &&
!(nc && *(nptr-1)=='\'') ) // ignore '=' case
while(*++nptr && (skips || skipc || (*nptr!=',' && *nptr!=')' || plevel!=1) )) {
if ( *nptr=='"' && *(nptr-1)!='\\' )
skips = skips ? 0 : 1;
else if(!skips && *nptr=='\'' && *(nptr-1)!='\\')
skipc = skipc ? 0 : 1;
if (!skips && !skipc && *nptr=='(') plevel++;
else if (!skips && *nptr==')') plevel--;
}
if (sptr < (s + sizeof(s) - 1)) *sptr++ = *nptr;
}
*sptr = '\0';
write_c("%s::%s {\n", k, s);
} else {
if (public_) {
if (cdecl_)
write_h("extern \"C\" { %s%s %s; }\n", rtype, star, name());
else
write_h("%s%s %s;\n", rtype, star, name());
}
else write_c("static ");
write_c("%s%s %s {\n", rtype, star, name());
}
}
if (havewidgets) write_c(" %s* w;\n",subclassname(child));
indentation += 2;
}
void Fl_Function_Type::write_code2() {
if (ismain()) {
if (havewidgets) write_c(" w->show(argc, argv);\n");
write_c(" return Fl::run();\n");
} else if (havewidgets && !constructor && !return_type)
write_c(" return w;\n");
write_c("}\n");
indentation = 0;
}
////////////////////////////////////////////////////////////////
Fl_Type *Fl_Code_Type::make() {
Fl_Type *p = Fl_Type::current;
while (p && !p->is_code_block()) p = p->parent;
if (!p) {
fl_message("Please select a function");
return 0;
}
Fl_Code_Type *o = new Fl_Code_Type();
o->name("printf(\"Hello, World!\\n\");");
o->add(p);
o->factory = this;
return o;
}
void Fl_Code_Type::open() {
if (!code_panel) make_code_panel();
const char *text = name();
code_input->buffer()->text( text ? text : "" );
code_panel->show();
const char* message = 0;
for (;;) { // repeat as long as there are errors
if (message) fl_alert(message);
for (;;) {
Fl_Widget* w = Fl::readqueue();
if (w == code_panel_cancel) goto BREAK2;
else if (w == code_panel_ok) break;
else if (!w) Fl::wait();
}
char*c = code_input->buffer()->text();
message = c_check(c); if (message) continue;
name(c);
free(c);
break;
}
BREAK2:
code_panel->hide();
}
Fl_Code_Type Fl_Code_type;
void Fl_Code_Type::write_code1() {
const char* c = name();
if (!c) return;
write_c("%s%s\n", indent(), c);
}
void Fl_Code_Type::write_code2() {}
////////////////////////////////////////////////////////////////
Fl_Type *Fl_CodeBlock_Type::make() {
Fl_Type *p = Fl_Type::current;
while (p && !p->is_code_block()) p = p->parent;
if (!p) {
fl_message("Please select a function");
return 0;
}
Fl_CodeBlock_Type *o = new Fl_CodeBlock_Type();
o->name("if (test())");
o->after = 0;
o->add(p);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?