Q3CString Dialog::digest(const QString s) { Q3CString c = (const char *) s; int index; index = 0; while ((index = c.find("\\n", index)) != -1) { c.replace(index, 2, "\n"); index += 1; } index = 0; while ((index = c.find("\\t", index)) != -1) { c.replace(index, 2, "\t"); index += 1; } index = 0; while ((index = c.find("\r", index)) != -1) { c.remove(index, 1); } return c; }
void UmlPackage::fileControl(bool ci) { UmlPackage * prj = getProject(); Q3CString prjfile = prj->supportFile(); BooL rec; BooL reload; Q3CString cmd; if (! prj->propertyValue((ci) ? "check-in-cmd" : "check-out-cmd", cmd)) cmd = "specify the command containing %file and %dir or %dironly"; Dialog dialog(ci, cmd, rec, reload); // the dialog execution set 'cmd' and 'rec' if (dialog.exec() == QDialog::Accepted) { // save the command for a future usage prj->set_PropertyValue((ci) ? "check-in-cmd" : "check-out-cmd", cmd); if (reload) saveProject(); // get files list Q3Dict<void> files; getFiles(files, (rec) ? ~0u : 1); if (this == prj) getAuxFiles(files); // apply the command on each file Q3DictIterator<void> it(files); QFileInfo prjpath(prjfile); QString dir = prjpath.dirPath(TRUE); QString dironly = dir; int index; if ((dironly.length() > 3) && (((const char *) dironly)[1] == ':') && (((const char *) dironly)[2] == '/')) dironly = dironly.mid(2); while ((index = cmd.find("%dironly")) != -1) cmd.replace(index, 8, dironly); while ((index = cmd.find("%dir")) != -1) cmd.replace(index, 4, dir); while (it.current()) { QString s = cmd; while ((index = s.find("%file")) != -1) s.replace(index, 5, it.currentKey()); system((const char *) s); ++it; } UmlCom::trace("Done."); if (reload) loadProject(prjfile); } }
void UmlRelation::compute_dependency(Q3PtrList<CppRefType> & dependencies, const Q3CString & cl_stereotype, bool all_in_h) { if (cl_stereotype == "enum") return; switch (relationKind()) { case aDependency: if (stereotype() == "friend") break; CppRefType::add(roleType(), dependencies, cppDecl() != "#include in source", roleType()->isCppExternal()); break; case aGeneralisation: case aRealization: CppRefType::add(roleType(), dependencies, TRUE); break; default: Q3CString decl = cppDecl(); int index; if ((index = decl.find("${static}")) != -1) decl.remove((unsigned) index, 9); if ((index = decl.find("${mutable}")) != -1) decl.remove((unsigned) index, 10); if ((index = decl.find("${volatile}")) != -1) decl.remove((unsigned) index, 11); if ((index = decl.find("${const}")) != -1) decl.remove((unsigned) index, 8); if ((index = decl.find("${multiplicity}")) != -1) decl.remove((unsigned) index, 15); if ((index = decl.find("${name}")) != -1) decl.remove((unsigned) index, 7); if ((index = decl.find("${inverse_name}")) != -1) decl.remove((unsigned) index, 15); if ((index = decl.find("${value}")) != -1) decl.remove((unsigned) index, 8); if ((index = decl.find("${h_value}")) != -1) decl.remove((unsigned) index, 10); if ((index = decl.find("${stereotype}")) != -1) decl.replace((unsigned) index, 13, CppSettings::relationAttributeStereotype(stereotype())); if ((index = decl.find("${association}")) != -1) { decl.replace((unsigned) index, 14, association().toString()); } replace_alias(decl); UmlTypeSpec type; type.type = roleType(); UmlClassMember::compute_dependency(dependencies, decl, type, all_in_h); } }
void UmlClassMember::write_type(FileOut & out, const UmlTypeSpec & t, Q3CString s, const char * k_name, const char * k_type) { s = s.simplifyWhiteSpace(); int index; // remove k_name and all after it except [] if (k_name && *k_name && ((index = s.find(k_name, 0)) != -1)) {//[rageek] Removed CS=FALSE - rethink this, case sensitive //remove name s.remove(index, strlen(k_name)); for (;;) { if (s[index] == ' ') s.remove(index, 1); if (s[index] != '[') break; index += 1; int index2; if ((index2 = s.find(index, ']')) == -1) break; index = index2 + 1; } s.resize(index); } else if ((index = s.find('=')) != -1) { s.resize(index); s = s.simplifyWhiteSpace(); } if (k_type && *k_type && ((index = s.find(k_type)) == -1)) out.idref_datatype(s); else if (s != k_type) { // have modifiers if (t.type != 0) { s.replace(index, strlen(k_type), t.type->name()); out.idref(s, t.type); } else out.idref_datatype(s.replace(index, strlen(k_type), t.explicit_type)); } else if (t.type != 0) out.idref(t.type); else out.idref_datatype(t.explicit_type); }
void UmlClassMember::remove_comments(Q3CString & s) { int index1 = 0; if ((index1 = s.find("${comment}")) != -1) s.remove((unsigned) index1, 10); else if ((index1 = s.find("${description}")) != -1) s.remove((unsigned) index1, 14); while ((index1 = s.find('/', index1)) != -1) { int index2; switch (((const char *) s)[index1 + 1]) { case '/': if ((index2 = s.find('\n', index1 + 2)) != -1) s.remove(index1, index2 - index1 + 1); else s.truncate(index1); break; case '*': if ((index2 = s.find("*/", index1 + 2)) != -1) s.replace(index1, index2 - index1 + 1, " "); else s.truncate(index1); break; default: index1 += 1; } } }
static void create_directory(Q3CString s) { int index = 0; QChar sep = QDir::separator(); if (sep != '/') { while ((index = s.find(sep, index)) != -1) s.replace(index++, 1, "/"); } s = QDir::cleanDirPath(s) + "/"; index = s.find("/"); int index2; while ((index2 = s.find("/", index + 1)) != -1) { Q3CString s2 = s.left(index2); QDir sd(s2); if (!sd.exists()) { if (!sd.mkdir(s2)) { UmlCom::trace(Q3CString("<font color=\"red\"><b> cannot create directory <i>") + s2 + "</i></b></font><br>"); UmlCom::bye(n_errors() + 1); UmlCom::fatal_error("UmlPackage::file_path"); } } index = index2; } }
void UmlItem::replace_alias(Q3CString & s) { int index = 0; while ((index = s.find("@{", index)) != -1) { int index2 = s.find('}', index + 2); if (index2 == -1) return; UmlBaseItem * obj = this; Q3CString key = s.mid(index + 2, index2 - index - 2); Q3CString value; for (;;) { if (obj->propertyValue(key, value)) { s.replace(index, index2 - index + 1, value); index += value.length(); break; } else if ((obj = obj->parent()) == 0) { index = index2 + 1; break; } } } }
void UmlExitPointPseudoState::html(Q3CString pfix, unsigned int rank, unsigned int level) { define(); UmlCom::message(name()); Q3CString s = sKind(); s.replace(0, 1, s.left(1).upper()); UmlItem::html(s, (UmlDiagram *) 0); fw.write("<p>Defined in "); if (parent()->kind() == aRegion) parent()->parent()->write(); else parent()->write(); fw.write("</p>"); if (reference() != 0) { fw.write("<p>References "); reference()->write(); fw.write("</p>"); } write_children(pfix, rank, level); unload(FALSE, FALSE); }
void UmlClass::write(QTextOStream & f) { if (isJavaExternal()) { Q3CString s = javaDecl().stripWhiteSpace(); int index; if ((index = s.find("${name}")) != -1) s.replace(index, 7, name()); else if ((index = s.find("${Name}")) != -1) s.replace(index, 7, capitalize(name())); else if ((index = s.find("${NAME}")) != -1) s.replace(index, 7, name().upper()); else if ((index = s.find("${nAME}")) != -1) s.replace(index, 7, name().lower()); f << s; } else { UmlClass * toplevel = this; UmlItem * p; Q3CString s2; while ((p = toplevel->parent())->kind() == aClass) { toplevel = (UmlClass *) p; s2 = dot + p->name() + s2; } UmlArtifact * cp = toplevel->associatedArtifact(); UmlPackage * pack = (UmlPackage *) ((cp != 0) ? (UmlItem *) cp : (UmlItem *) toplevel)->package(); if (pack != UmlArtifact::generation_package()) { Q3CString s = pack->javaPackage(); if (! s.isEmpty() && (s != "java.lang") && (s.left(10) != "java.lang.")) { s += s2; if (JavaSettings::isForcePackagePrefixGeneration() || !UmlArtifact::generated_one()->is_imported(s, name())) f << s << '.'; } } else if (! s2.isEmpty()) f << s2.mid(1) << '.'; f << name(); } }
bool UmlAttribute::new_one(Class * container, Q3CString name, aVisibility visibility, bool constp, bool staticp, const Q3CString & value, Q3CString comment, Q3CString description) { #ifdef TRACE cout << "ATTRIBUTE '" << name << "'\n"; #endif #ifndef REVERSE if (visibility == PrivateVisibility) return TRUE; #endif if (((const char *) name)[0] == '$') name = name.mid(1); UmlClass * cl = container->get_uml(); UmlAttribute * at = UmlBaseAttribute::create(cl, name); if (at == 0) { PhpCatWindow::trace(Q3CString("<font face=helvetica><b>cannot add attribute <i>") + name + "</i> in <i>" + cl->name() + "</i></b></font><br>"); return FALSE; } #ifdef REVERSE Statistic::one_attribute_more(); #endif if (!comment.isEmpty()) { Q3CString s = (at->phpDecl().find("${description}") != -1) ? description : comment; UmlTypeSpec t; int index; if (! (t.explicit_type = value_of(s, "@var", index)).isEmpty()) { at->set_Type(t); s.replace(index, t.explicit_type.length(), "${type}"); } at->set_Description(s); } if (constp) at->set_isReadOnly(TRUE); if (staticp) at->set_isClassMember(TRUE); if (! value.isEmpty()) at->set_DefaultValue(value); at->set_Visibility(visibility); return TRUE; }
void UmlClassMember::remove_comments(Q3CString & s) { int index; if ((index = s.find("${comment}")) != -1) s.replace(index, 10, " "); index = 0; while ((index = s.find('#', index)) != -1) { int index2 = s.find('\n', index + 1); if (index2 == -1) { s.resize(index); break; } s.remove(index, index2 - index); } index = 0; while ((index = s.find("//", index)) != -1) { int index2 = s.find('\n', index + 2); if (index2 == -1) { s.resize(index); break; } s.remove(index, index2 - index); } index = 0; while ((index = s.find("/*", index)) != -1) { int index2 = s.find("*/", index + 2); if (index2 == -1) { s.resize(index); break; } s.replace(index, index2 + 2 - index, " "); } s = s.simplifyWhiteSpace(); }
void UmlClass::importIdlConstant(UmlItem * parent, const Q3CString & id, const Q3CString & s, const Q3CString & doc, Q3Dict<Q3CString> & prop) { // use a class to define the constant ! UmlClass * x; if ((x = UmlClass::create(parent, legalName(s))) == 0) { UmlCom::trace("<br>cannot create class '" + s + "' in " + parent->fullName()); throw 0; } newItem(x, id); x->lang = Corba; x->set_Stereotype("constant"); if (!doc.isEmpty()) x->set_Description(doc); Q3CString type; Q3CString value; Q3CString * v; if ((v = prop.find("CORBA/ImplementationType")) != 0) { type = *v; prop.remove("CORBA/ImplementationType"); } if ((v = prop.find("CORBA/ConstValue")) != 0) { if (!v->isEmpty()) value = " = " + *v; prop.remove("CORBA/ConstValue"); } Q3CString d = IdlSettings::constDecl(); int index; if ((index = d.find("${type}")) != -1) d.replace(index, 7, type); if ((index = d.find("${value}")) != -1) d.replace(index, 8, value); x->setProperties(prop); x->set_IdlDecl(d); }
void UmlAttribute::write_cpp_type(FileOut & out) { // note : doesn't manage function/operation pointer Q3CString s = cppDecl(); int index; remove_comments(s); // remove keywords not linked to the type if ((index = s.find("${static}")) != -1) s.replace(index, 9, " "); if ((index = s.find("${mutable}")) != -1) s.replace(index, 10, (isCppMutable()) ? "mutable " : ""); if ((index = s.find("${volatile}")) != -1) s.replace(index, 11, (isVolatile()) ? "volatile " : ""); if ((index = s.find("${value}")) != -1) s.replace(index, 8, " "); if ((index = s.find("${h_value}")) != -1) s.replace(index, 10, " "); // replace keywords linked to the type if ((index = s.find("${const}")) != -1) s.replace(index, 8, isReadOnly() ? "const" : ""); UmlTypeSpec t = type(); if (t.type == 0) t.explicit_type = CppSettings::type(t.explicit_type); write_type(out, t, s, "${name}", "${type}"); }
void UmlClassMember::remove_arrays(Q3CString & s) { int index1 = 0; while ((index1 = s.find('[', index1)) != -1) { int index2 = index1 = s.find(']', index1 + 1); if (index2 == -1) { s.truncate(index1); return; } else s.replace(index1, index2 - index1 + 1, " "); } }
void UmlAttribute::compute_dependency(Q3PtrList<CppRefType> & dependency, const Q3CString & cl_stereotype, bool all_in_h) { if ((cl_stereotype == "enum") || (cl_stereotype == "typedef")) return; Q3CString decl = cppDecl(); int index; if ((index = decl.find("${static}")) != -1) decl.remove((unsigned) index, 9); if ((index = decl.find("${mutable}")) != -1) decl.remove((unsigned) index, 10); if ((index = decl.find("${volatile}")) != -1) decl.remove((unsigned) index, 11); if ((index = decl.find("${const}")) != -1) decl.remove((unsigned) index, 8); if ((index = decl.find("${multiplicity}")) != -1) decl.remove((unsigned) index, 15); if ((index = decl.find("${value}")) != -1) decl.remove((unsigned) index, 8); if ((index = decl.find("${h_value}")) != -1) decl.remove((unsigned) index, 10); if ((index = decl.find("${name}")) != -1) decl.remove((unsigned) index, 7); if ((index = decl.find("${stereotype}")) != -1) decl.replace((unsigned) index, 13, CppSettings::relationAttributeStereotype(stereotype())); replace_alias(decl); if (!UmlClassMember::compute_dependency(dependency, decl, type(), all_in_h)) { write_trace_header(); UmlCom::trace(Q3CString(" <font color=\"red\"><b>type missing for attribute <i>") + name() + "</i></b></font><br>"); incr_error(); } }
QString Namespace::namespacify(Q3CString s, bool local) { QString r; int index = s.find("::"); if (index == 0) r = ((const char *) s) + 2; else { if (index != -1) { QMap<Q3CString,Q3CString>::ConstIterator it = Aliases.find(s.left(index)); if (it != Aliases.end()) s.replace(0, index, *it); } r = (Stack.isEmpty()) ? QString(s) : Stack.last() + QString(s); } return (local) ? r + "\n" + Lex::filename() : r; }
void UmlAttribute::write_java_type(FileOut & out) { Q3CString s = javaDecl(); int index; remove_comments(s); // remove keywords not linked to the type if ((index = s.find("${visibility}")) != -1) s.replace(index, 13, " "); if ((index = s.find("${static}")) != -1) s.replace(index, 9, " "); if ((index = s.find("${final}")) != -1) s.replace(index, 8, " "); if ((index = s.find("${transient}")) != -1) s.replace(index, 12, " "); if ((index = s.find("${volatile}")) != -1) s.replace(index, 11, " "); if ((index = s.find("${value}")) != -1) s.replace(index, 8, " "); if ((index = s.find("${@}")) != -1) s.replace(index, 4, " "); UmlTypeSpec t = type(); if (t.type == 0) t.explicit_type = JavaSettings::type(t.explicit_type); write_type(out, t, s, "${name}", "${type}"); }
bool UmlOperation::new_one(Class * container, const Q3CString & name, const Q3ValueList<FormalParameterList> & tmplts, const Q3CString & oper_templ, UmlTypeSpec & type, Q3CString str_actuals, UmlClass * first_actual_class, Q3CString type_def, aVisibility visibility, bool finalp, bool abstractp, bool staticp, bool nativep, bool strictfp, bool synchronizedp, const Q3CString & array, Q3CString comment, Q3CString description, Q3CString annotation #ifdef ROUNDTRIP , bool roundtrip, Q3PtrList<UmlItem> & expected_order #endif ) { // the "(" was read #ifdef TRACE QLOG_INFO() <<"OPERATION '" << name << "'\n"; #endif UmlClass * cl = container->get_uml(); UmlOperation * op; #ifdef ROUNDTRIP bool may_roundtrip = roundtrip && (!container->from_libp() || (visibility != PrivateVisibility)); UmlTypeSpec return_type; Q3ValueList<UmlParameter> params; Q3ValueList<UmlTypeSpec> exceptions; Q3CString body; if (may_roundtrip) #else if ( # ifdef REVERSE container->from_libp() && # endif (visibility == PrivateVisibility)) #endif op = 0; else { op = UmlBaseOperation::create(cl, name); if (op == 0) { JavaCatWindow::trace(Q3CString("<font face=helvetica><b>cannot add operation <i>") + name + "</i> in <i>" + cl->name() + "</i></b></font><br>"); return FALSE; } #ifndef ROUNDTRIP # if defined(REVERSE) Statistic::one_operation_more(); # endif #endif } Q3CString def; #ifdef ROUNDTRIP if (may_roundtrip || (op != 0)) { #else if (op != 0) { op->set_Visibility(visibility); if (staticp) op->set_isClassMember(TRUE); if (abstractp) op->set_isAbstract(TRUE); if (finalp) op->set_isJavaFinal(TRUE); if (synchronizedp) op->set_isJavaSynchronized(TRUE); if (! annotation.isEmpty()) op->set_JavaAnnotations(annotation); #endif def = JavaSettings::operationDef(); int index; if (((index = def.find("${(}")) == -1) || ((index = def.find("${)}", index + 4)) == -1) || ((index = def.find("${throws}", index + 4)) == -1) || (def.find("${body}", index + 9) == -1) || ((index = def.find("${type}")) == -1)) { // use a definition where ${body] is not indented def = " ${comment}${@}${visibility}${final}${static}${abstract}${synchronized}${type} ${name}${(}${)}${throws}${staticnl}{\n${body}}\n"; index = def.find("${type}"); } if (!array.isEmpty()) def.insert(index + 7, (const char *)array); if (nativep) { def.insert(index, "native "); index += 7; // no body int index2 = def.find("${throws}", index+7); if (index2 != -1) { def.resize(index2 + 12); def[index2 + 9] = ';'; def[index2 + 10] = '\n'; } } if (strictfp) { def.insert(index, "strictfp "); index += 9; } if (! oper_templ.isEmpty()) def.insert(index, (const char *)(oper_templ + " ")); if (name == cl->name()) { // constructor, remove useless ${} if ((index = def.find("${static}")) != -1) def.remove(index, 9); if ((index = def.find("${type}")) != -1) def.remove(index, (((const char *) def)[index + 7] == ' ') ? 8 : 7); if ((index = def.find("${final}")) != -1) def.remove(index, 8); if ((index = def.find("${abstract}")) != -1) def.remove(index, 11); } if (type.type != 0) { UmlClass::manage_generic(def, type, str_actuals, "${type}"); #ifdef ROUNDTRIP return_type = type; #else op->set_ReturnType(type); #endif } else if (first_actual_class != 0) { #ifndef ROUNDTRIP UmlTypeSpec return_type; #endif return_type.type = first_actual_class; def.replace(def.find("${type}"), 7, type_def); #ifndef ROUNDTRIP op->set_ReturnType(return_type); #endif } else if (!type.explicit_type.isEmpty()) { // not a contructor #ifdef ROUNDTRIP return_type = type; #else op->set_ReturnType(type); #endif } } // parameters unsigned rank = 0; UmlParameter param; #ifdef ROUNDTRIP if (may_roundtrip) while (read_param(container, rank++, tmplts, param, def, FALSE)) params.append(param); else #endif while (read_param(container, rank, tmplts, param, def, op == 0)) { if ((op != 0) && ! op->addParameter(rank, param)) { JavaCatWindow::trace(Q3CString("<font face=helvetica><b>cannot add param <i>") + name + "</i> in <i>" + cl->name() + "</i></b></font><br>"); # ifdef TRACE QLOG_INFO() <<"ERROR cannot add param '" << param.name << "' type '" << param.type.Type() << '\n'; # endif return FALSE; } rank += 1; } Q3CString s = Lex::read_word(); if (!s.isEmpty() && (*((const char *) s) == '[')) { #ifdef ROUNDTRIP if (may_roundtrip) #else if (op != 0) #endif // do not place it at the same place def.insert(def.find("${type}") + 7, (const char *)s); s = Lex::read_word(); } if (s.isEmpty()) { Lex::premature_eof(); return FALSE; } if (s == "throws") { // throws rank = 0; for (;;) { if ((s = Lex::read_word()).isEmpty()) { Lex::premature_eof(); return FALSE; } #ifdef ROUNDTRIP if (may_roundtrip) { UmlTypeSpec typespec; container->compute_type(s, typespec, tmplts); exceptions.append(typespec); } else #endif if (op != 0) { UmlTypeSpec typespec; container->compute_type(s, typespec, tmplts); if (! op->addException(rank++, typespec)) { # ifdef TRACE QLOG_INFO() <<"cannot add exception " << s << '\n'; # endif return FALSE; } } if (((s = Lex::read_word()) == "{") || (s == ";")) break; if (s != ",") { Lex::error_near(s, " ',' expected"); return FALSE; } } } // definition if (abstractp || nativep || (cl->stereotype() == "interface") || (cl->stereotype() == "@interface")) { if ((s == "default") && (cl->stereotype() == "@interface")) { int index = def.find("${)}"); Lex::mark(); s = Lex::read_word(); if (s == "{") { int level = 1; char c; for (;;) { if ((c = Lex::read_word_bis()) == 0) return FALSE; else if (c == '{') level += 1; else if ((c == '}') && (--level == 0)) break; } s = Lex::region(); } def.insert(index + 4, (const char *)(" default" + s)); s = Lex::read_word(); } if (s != ";") { Lex::error_near(s, " ';' expected"); return FALSE; } #ifdef REVERSE # ifndef ROUNDTRIP if ((op != 0) && !container->from_libp()) op->set_JavaBody(0); # endif #endif } else if (s != "{") { Lex::error_near(s, " '{' expected"); return FALSE; } else { Lex::mark(); // goto the end of the body #ifndef ROUNDTRIP Q3CString body; #endif int level = 1; // '{' already read char c; for (;;) { if ((c = Lex::read_word_bis()) == 0) return FALSE; else if (c == '{') level += 1; else if ((c == '}') && (--level == 0)) break; } #ifdef REVERSE if ( # ifdef ROUNDTRIP may_roundtrip || (op != 0) # else (op != 0) && !container->from_libp() # endif ) { body = Lex::region(); body.truncate(body.length() - 1); // remove } // remove fist \n if (*((const char *) body) == '\n') body.remove(0, 1); // remove last spaces and tabs int ln = body.length(); while (ln && ((body[ln - 1] == ' ') || (body[ln - 1] == '\t'))) ln -= 1; body.truncate(ln); if (!body.isEmpty() && (body[ln - 1] != '\n')) body += "\n"; # ifndef ROUNDTRIP op->set_JavaBody(body); op->set_JavaContextualBodyIndent(FALSE); # endif } #endif } #ifdef ROUNDTRIP if (may_roundtrip) { if (((op = already_exist_from_id(container, body)) != 0) || ((op = already_exist(container, name, params)) != 0)) { // update already existing operation op->set_usefull(); { // remove \r in case of preserve body Q3CString current_body = op->javaBody(); int index = 0; while ((index = current_body.find('\r', index)) != -1) current_body.remove(index, 1); if (nequal(current_body, body)) { container->set_updated(); op->set_JavaBody(body); op->set_JavaContextualBodyIndent(FALSE); } } if (op->visibility() != visibility) { container->set_updated(); op->set_Visibility(visibility); } if (op->isClassMember() != staticp) { container->set_updated(); op->set_isClassMember(staticp); } if (op->isAbstract() != abstractp) { container->set_updated(); op->set_isAbstract(abstractp); } if (op->isJavaFinal() != finalp) { container->set_updated(); op->set_isJavaFinal(finalp); } if (op->isJavaSynchronized() != synchronizedp) { container->set_updated(); op->set_isJavaSynchronized(synchronizedp); } if (nequal(op->javaAnnotations(), annotation)) { container->set_updated(); op->set_JavaAnnotations(annotation); } if (!op->returnType().equal(return_type)) { container->set_updated(); op->set_ReturnType(return_type); } Q3ValueList<UmlParameter>::Iterator itp1; const Q3ValueList<UmlParameter> old_params = op->params(); Q3ValueList<UmlParameter>::ConstIterator itp2; for (rank = 0, itp1 = params.begin(), itp2 = old_params.begin(); (itp1 != params.end()) && (itp2 != old_params.end()); ++itp1, ++itp2, rank += 1) { UmlParameter & p1 = *itp1; const UmlParameter & p2 = *itp2; if ((p1.name != p2.name) || nequal(p1.default_value, p2.default_value) || !p1.type.equal(p2.type)) { if (p1.dir != InputDirection) p1.dir = p2.dir; op->replaceParameter(rank, p1); container->set_updated(); } else if ((p1.dir == InputDirection) && (p2.dir != InputDirection)) { op->replaceParameter(rank, p1); container->set_updated(); } } if (itp1 != params.end()) { // have missing params container->set_updated(); do { op->addParameter(rank, *itp1); itp1++; rank += 1; } while (itp1 != params.end()); } else if (itp2 != old_params.end()) { // have extra params container->set_updated(); do { op->removeParameter(rank); itp2++; } while (itp2 != old_params.end()); } Q3ValueList<UmlTypeSpec>::ConstIterator ite1; const Q3ValueList<UmlTypeSpec> old_exceptions = op->exceptions(); Q3ValueList<UmlTypeSpec>::ConstIterator ite2; for (rank = 0, ite1 = exceptions.begin(), ite2 = old_exceptions.begin(); (ite1 != exceptions.end()) && (ite2 != old_exceptions.end()); ++ite1, ++ite2, rank += 1) { const UmlTypeSpec & e1 = *ite1; if (!e1.equal(*ite2)) { op->replaceException(rank, e1); container->set_updated(); } } if (ite1 != exceptions.end()) { // have missing exceptions container->set_updated(); do { op->addException(rank, *ite1); ite1++; rank += 1; } while (ite1 != exceptions.end()); } else if (ite2 != old_exceptions.end()) { // have extra exceptions container->set_updated(); do { op->removeException(rank); ite2++; } while (ite2 != old_exceptions.end()); } if (neq(def, op->javaDecl())) { container->set_updated(); op->set_JavaDecl(def); } Lex::clear_comments(); // params & body comments Lex::finish_line(); if (def.find("${description}") != -1) { if (nequal(op->description(), description)) { container->set_updated(); op->set_Description(description); } } else if (nequal(op->description(), Lex::simplify_comment(comment))) { op->set_Description(comment); // comment was set container->set_updated(); } expected_order.append(op); return TRUE; } // operation doesn't yet exist container->set_updated(); op = UmlBaseOperation::create(cl, name); if (op == 0) { JavaCatWindow::trace(Q3CString("<font face=helvetica><b>cannot add operation <i>") + name + "</i> in <i>" + cl->name() + "</i></b></font><br>"); throw 0; } expected_order.append(op); Q3ValueList<UmlParameter>::ConstIterator itp; for (rank = 0, itp = params.begin(); itp != params.end(); ++itp) op->addParameter(rank++, *itp); Q3ValueList<UmlTypeSpec>::ConstIterator ite; for (rank = 0, ite = exceptions.begin(); ite != exceptions.end(); ++ite) op->addException(rank++, *ite); } if (op != 0) { op->set_JavaContextualBodyIndent(FALSE); op->set_Visibility(visibility); if (staticp) op->set_isClassMember(TRUE); if (abstractp) op->set_isAbstract(TRUE); if (finalp) op->set_isJavaFinal(TRUE); if (synchronizedp) op->set_isJavaSynchronized(TRUE); if (! annotation.isEmpty()) op->set_JavaAnnotations(annotation); op->set_JavaBody(body); op->set_ReturnType(return_type); if (def != JavaSettings::operationDef()) op->set_JavaDecl(def); } #else if ((op != 0) && (def != JavaSettings::operationDef())) op->set_JavaDecl(def); #endif Lex::clear_comments(); // params & body comments Lex::finish_line(); if (!comment.isEmpty()) if (op != 0) op->set_Description((def.find("${description}") != -1) ? description : Lex::simplify_comment(comment)); return TRUE; } bool UmlOperation::read_param(Class * container, unsigned rank, const Q3ValueList<FormalParameterList> & tmplts, UmlParameter & param, Q3CString & def, bool bypass) { #ifdef TRACE QLOG_INFO() <<"UmlOperation::manage_param " << rank << "\n"; #endif bool finalp = FALSE; bool in = FALSE; bool ellipsis = FALSE; Q3CString array; bool type_read = FALSE; Q3ValueList<UmlTypeSpec> actuals; Q3CString str_actuals; Q3CString annotation; param.name = param.default_value = 0; Q3CString s = Lex::read_word(); #ifdef TRACE QLOG_INFO() <<"commence par " << s << '\n'; #endif if (s == ")") return FALSE; for (;;) { if (s.isEmpty()) { Lex::premature_eof(); return FALSE; } else if (s == "final") finalp = TRUE; else if ((s == "void") || (s == "byte") || (s == "char") || (s == "short") || (s == "int") || (s == "long") || (s == "float") || (s == "double")) { if (type_read) { Lex::error_near(s); return FALSE; } param.type.type = 0; param.type.explicit_type = s; type_read = TRUE; in = TRUE; } else if ((s == ")") || (s == ",")) { if (param.name.isEmpty() && !type_read) { Lex::error_near(s); return FALSE; } if (s == ")") Lex::unread_word(s); if (! bypass) { param.dir = (finalp || in) ? InputDirection : InputOutputDirection; Q3CString s; if (rank != 0) s = ", "; if (! annotation.isEmpty()) s += annotation + " "; if (finalp) s += "final "; if ((param.type.type != 0) && !param.type.explicit_type.isEmpty()) s += param.type.explicit_type; else { s += "${t"; s += Q3CString().setNum(rank); s += "}"; if (param.type.type != 0) s += str_actuals; } s += array; s += (ellipsis) ? " ... ${p": " ${p"; s += Q3CString().setNum(rank); s += "}"; def.insert(def.find("${)}"), // cannot be -1 (const char *)s); } return TRUE; } else if (Lex::identifierp(s)) { if (!type_read) { while (s.at(s.length() - 1) == '.') { // type on several lines, managed in this case Q3CString s2 = Lex::read_word(); if (Lex::identifierp(s2)) s += s2; else { Lex::error_near(s, " identifier expected"); return FALSE; } } #ifdef TRACE QLOG_INFO() <<"type = '" << s << "...'\n"; #endif if (! bypass) { Q3CString dummy; container->read_type(param.type, 0, tmplts, 0, str_actuals, s, 0, dummy, dummy); if (param.type.explicit_type == "String") // at least for it ! in = TRUE; } else Lex::bypass_type(s); type_read = TRUE; } else if (param.name.isEmpty()) { if (s == "...") ellipsis = TRUE; else { param.name = s; #ifdef TRACE QLOG_INFO() <<"name = '" << param.name << "'\n"; #endif } } else { Lex::error_near(s); #ifdef TRACE QLOG_INFO() <<"ERROR '" << s << "' alors qu a deja le type et le nom '" << param.name << "'\n"; #endif return FALSE; } } else if (*((const char *) s) == '@') annotation = s; else if (*((const char *) s) == '[') { in = FALSE; array = s; } else { Lex::error_near(s); #ifdef TRACE QLOG_INFO() <<"ERROR : '" << s << "'\n"; #endif return FALSE; } s = Lex::read_word(); } }
Q3CString UmlPackage::file_path(const Q3CString & f, Q3CString relto) { if (!dir.read) { dir.file = phpDir(); dir.file_absolute = FALSE; QDir d_root(rootDir()); if (dir.file.isEmpty()) dir.file = RootDir; else if (QDir::isRelativePath(dir.file)) dir.file = d_root.filePath(dir.file); else dir.file_absolute = TRUE; if (dir.file.isEmpty()) { UmlCom::trace(Q3CString("<font color=\"red\"><b><b> The generation directory " "must be specified for the package<i> ") + name() + "</i>, edit the <i> generation settings</i> (tab 'directory') " "or edit the package (tab 'Php')</b></font><br>"); UmlCom::bye(n_errors() + 1); UmlCom::fatal_error("UmlPackage::file_path"); } dir.read = TRUE; } if (f.isEmpty()) return dir.file; QDir d(dir.file); if (! d.exists()) { // create directory including the intermediates Q3CString s = dir.file; int index = 0; QChar sep = QDir::separator(); if (sep != '/') { while ((index = s.find(sep, index)) != -1) s.replace(index++, 1, "/"); } s = QDir::cleanDirPath(s) + "/"; index = s.find("/"); int index2; while ((index2 = s.find("/", index + 1)) != -1) { Q3CString s2 = s.left(index2); QDir sd(s2); if (!sd.exists()) { if (!sd.mkdir(s2)) { UmlCom::trace(Q3CString("<font color=\"red\"><b> cannot create directory <i>") + s2 + "</i></b></font><br>"); UmlCom::bye(n_errors() + 1); UmlCom::fatal_error("UmlPackage::file_path"); } } index = index2; } } Q3CString df = (dir.file_absolute || relto.isEmpty()) ? Q3CString(d.filePath(f).toAscii().constData()) : relative_path(d, relto) + f; if (PhpSettings::isRelativePath() && (df[0] != '/') && (df[0] != '.')) df = "./" + df; return df + Q3CString(".") + PhpSettings::sourceExtension(); }
Q3CString UmlParameter::cpp(unsigned rank) const { Q3CString s; int index; if ((type.type != 0) && (CppSettings::classStereotype(type.type->stereotype()) == "enum")) { switch (dir) { case InputDirection: s = CppSettings::enumIn(); break; case OutputDirection: s = CppSettings::enumOut(); break; default: // can't be return s = CppSettings::enumInout(); break; } } else { switch (dir) { case InputDirection: if (!type.explicit_type.isEmpty()) s = CppSettings::builtinIn(type.explicit_type); if (s.isEmpty()) s = CppSettings::in(); case OutputDirection: if (!type.explicit_type.isEmpty()) s = CppSettings::builtinOut(type.explicit_type); if (s.isEmpty()) s = CppSettings::out(); break; default: // can't be return if (!type.explicit_type.isEmpty()) s = CppSettings::builtinInout(type.explicit_type); if (s.isEmpty()) s = CppSettings::inout(); } } if ((index = s.find("${type}")) != -1) { Q3CString t; t.sprintf("${t%u}", rank); s.replace(index, 7, t); } Q3CString p; p.sprintf(" ${p%u}${v%u}", rank, rank); return s + p; }
bool UmlAttribute::new_one(Class * container, const Q3CString & name, const Q3CString & type, const Q3CString & modifier, const Q3CString & pretype, const Q3CString & array, aVisibility visibility, bool staticp, bool constp, bool typenamep, bool mutablep, bool volatilep, const Q3CString & bitfield, const Q3CString & value, Q3CString comment, Q3CString description #ifdef ROUNDTRIP , bool roundtrip, Q3PtrList<UmlItem> & expected_order #endif ) { #ifdef DEBUG_BOUML cout << "ATTRIBUTE '" << name << "' type '" << type << "' modifier '" << modifier << "' array '" << array << "'\n"; #endif if ( #ifdef REVERSE container->from_libp() && #endif (visibility == PrivateVisibility)) { Lex::finish_line(); Lex::clear_comments(); return TRUE; } UmlClass * cl = container->get_uml(); UmlAttribute * at; #ifdef ROUNDTRIP bool created; if (!roundtrip || ((at = search_attr(cl, name)) == 0)) { #endif at = UmlBaseAttribute::create(cl, name); if (at == 0) { UmlCom::trace(Q3CString("<font face=helvetica><b>cannot add attribute <i>") + name + "</i> in <i>" + Q3CString(cl->name()) + "</i></b></font><br><hr>"); return FALSE; } #ifdef REVERSE # ifndef ROUNDTRIP Statistic::one_attribute_more(); # else if (roundtrip) container->set_updated(); created = TRUE; } else created = FALSE; # endif #endif Lex::finish_line(); comment = Lex::get_comments(comment); description = Lex::get_description(description); bool pfunc = (type.find('$') != -1); UmlTypeSpec typespec; Q3CString typeform; Q3CString stereotype; if (! pfunc) { typeform = (pretype.isEmpty()) ? Q3CString("${type}") : pretype + " ${type}"; container->compute_type(type, typespec, typeform); } else { typespec.explicit_type = type.simplifyWhiteSpace(); int index = typespec.explicit_type.find("${name}"); if (index != -1) typespec.explicit_type.remove(index, 7); } Q3CString decl = CppSettings::attributeDecl(""); int index = decl.find("${type}"); if ((index == -1) || (decl.find("${const}") == -1) || (decl.find("${name}") == -1) || (decl.find("${mutable}") == -1) || (decl.find("${volatile}") == -1) || (decl.find(';') == -1)) { decl = " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value};"; index = decl.find("${type}"); } if (pfunc) decl.replace(index, decl.find("${name}") + 7 - index, type); else { if (!modifier.isEmpty()) decl.insert(index + 7, (const char*)(Q3CString(" ") + modifier)); if (typeform != "${type}") decl.replace(index, 7, typeform); else if (typespec.type == 0) { Q3CString t = typespec.explicit_type; int index2; if (!t.isEmpty() && (t.at(t.length() - 1) == '>') && ((index2 = t.find('<')) > 0)) { stereotype = t.left(index2); typespec.explicit_type = // may be a,b ... t.mid(index2 + 1, t.length() - 2 - index2); decl.replace(index, 7, "${stereotype}<${type}>"); } } if (!array.isEmpty()) decl.insert(decl.find("${name}") + 7, "${multiplicity}"); if (!bitfield.isEmpty()) decl.insert(decl.find(';'), (const char *)(Q3CString(" : ") + bitfield)); } if (typenamep) { int index = decl.find("${const}") + 8; // find cannot return -1 int index2 = decl.find("${mutable}") + 10; // find cannot return -1 int index3 = decl.find("${volatile}") + 11; // find cannot return -1 if (index2 > index) index = index2; if (index3 > index) index = index3; decl.insert(index, "typename "); } if (!value.isEmpty() && ((index = decl.find("${value}")) != -1)) decl.insert(index + 2, "h_"); #ifdef ROUNDTRIP if (roundtrip && !created) { if (decl.find("${description}") != -1) { if (nequal(at->description(), description)) { at->set_Description(description); container->set_updated(); } } else if (nequal(at->description(), Lex::simplify_comment(comment))) { at->set_Description(comment); // comment was set container->set_updated(); } if (at->isReadOnly() != constp) { at->set_isReadOnly(constp); container->set_updated(); } if (at->isCppMutable() != mutablep) { at->set_isCppMutable(mutablep); container->set_updated(); } if (at->isVolatile() != volatilep) { at->set_isVolatile(volatilep); container->set_updated(); } if (at->isClassMember() != staticp) { at->set_isClassMember(staticp); container->set_updated(); } if (neq(at->multiplicity(), array)) { at->set_Multiplicity(array); container->set_updated(); } if (!staticp) { Q3CString v = at->defaultValue(); if (!v.isEmpty() && (((const char *) v)[0] == '=')) v = v.mid(1); if (nequal(v, value)) { at->set_DefaultValue(value); container->set_updated(); } } if (at->visibility() != visibility) { at->set_Visibility(visibility); container->set_updated(); } if (!stereotype.isEmpty()) { Q3CString cppst; if (!at->stereotype().isEmpty()) cppst = CppSettings::relationAttributeStereotype(at->stereotype()); if (cppst != stereotype) { at->set_Stereotype(stereotype); container->set_updated(); } } if (!at->type().equal(typespec)) { at->set_Type(typespec); container->set_updated(); } if (neq(at->cppDecl(), decl)) { at->set_CppDecl(decl); container->set_updated(); } at->set_usefull(); expected_order.append(at); } else { #endif if (!comment.isEmpty()) at->set_Description((decl.find("${description}") != -1) ? description : Lex::simplify_comment(comment)); if (constp) at->set_isReadOnly(TRUE); if (mutablep) at->set_isCppMutable(TRUE); if (volatilep) at->set_isVolatile(TRUE); if (staticp) at->set_isClassMember(TRUE); if (!array.isEmpty()) at->set_Multiplicity(array); if (! value.isEmpty()) at->set_DefaultValue(value); at->set_Visibility(visibility); if (! stereotype.isEmpty()) at->set_Stereotype(stereotype); at->set_Type(typespec); at->set_CppDecl(decl); #ifdef ROUNDTRIP if (roundtrip) expected_order.append(at); } #endif return TRUE; }
UmlClassView * UmlPackage::get_classview(const Q3CString & nmsp) { UmlPackage * pack; if (nmsp != cppNamespace()) { if (namespace_fixedp) { if ((pack = findCppNamespace(nmsp)) == 0) { Q3CString s = nmsp; if (s.isEmpty()) s = name(); else { int index = 0; while ((index = s.find("::", index)) != -1) s.replace(index++, 2, " "); } if (((pack = UmlBasePackage::create(this, s)) == 0) && ((pack = UmlBasePackage::create(this, s += "_")) == 0) && ((pack = UmlBasePackage::create(this, s += "_")) == 0) && ((pack = UmlBasePackage::create(this, s += "_")) == 0) && ((pack = UmlBasePackage::create(this, s += "_")) == 0)) { #ifdef REVERSE UmlCom::trace(Q3CString("<font face=helvetica><b>cannot create package <i>") + s + "</i> under package <i>" + name() + "</b></font><br>"); UmlCom::message(""); throw 0; #else QMessageBox::critical(0, "Fatal Error", Q3CString("<font face=helvetica><b>cannot create package <i>") + s + "</i> under package <i>" + Name() + "</b></font><br>"); QApplication::exit(1); #endif } pack->set_CppNamespace(nmsp); pack->set_CppSrcDir(cppSrcDir()); pack->set_CppHDir(cppHDir()); pack->namespace_fixedp = TRUE; } } else { pack = this; pack->set_CppNamespace(nmsp); pack->namespace_fixedp = TRUE; } } else pack = this; if (pack->class_view == 0) { Q3PtrVector<UmlItem> ch = pack->children(); for (unsigned index = 0; index != ch.size(); index += 1) // return the first class view find if (ch[index]->kind() == aClassView) return pack->class_view = (UmlClassView *) ch[index]; if ((pack->class_view = UmlBaseClassView::create(pack, name())) == 0) { #ifdef REVERSE UmlCom::trace(Q3CString("<font face=helvetica><b>cannot create class view <i>") + name() + "</i> under package <i>" + pack->name() + "</b></font><br>"); UmlCom::message(""); throw 0; #else QMessageBox::critical(0, "Fatal Error", Q3CString("<font face=helvetica><b>cannot create class view <i>") + name() + "</i> under package <i>" + pack->name() + "</b></font><br>"); QApplication::exit(1); #endif } } return pack->class_view; }
bool UmlRelation::new_one(Class * container, const Q3CString & name, UmlClass * dest, const Q3CString & modifier, const Q3CString & pretype, const Q3CString & array, const Q3CString & typeform, aVisibility visibility, bool staticp, bool constp, bool mutablep, bool volatilep, const Q3CString & value, Q3CString comment, Q3CString description #ifdef ROUNDTRIP , bool roundtrip, Q3PtrList<UmlItem> & expected_order #endif ) { #ifdef DEBUG_BOUML cout << "RELATION '" << name << "' from '" << cl->name() << "' to '" << dest->name() << "' modifier '" << modifier << "' array '" << array << "' typeform '" << typeform << "'\n"; #endif if ( #ifdef REVERSE container->from_libp() && #endif (visibility == PrivateVisibility)) { Lex::finish_line(); Lex::clear_comments(); return TRUE; } UmlClass * cl = container->get_uml(); UmlRelation * rel; #ifdef ROUNDTRIP if (roundtrip && ((rel = search_rel(container, name, dest, "")) != 0)) { rel->set_usefull(); expected_order.append(rel); } else { #endif rel = UmlBaseRelation::create((modifier.isEmpty() && ((typeform == "${type}") || (typeform[typeform.find("${type}") + 7] != '*'))) ? aDirectionalAggregationByValue : aDirectionalAssociation, cl, dest); if (rel == 0) { UmlCom::trace(Q3CString("<font face=helvetica><b>cannot add relation <i>") + name + "</i> in <i>" + cl->name() + "</i> to <i>" + dest->name() + "</i></b></font><br><hr>"); return FALSE; } #ifdef REVERSE # ifndef ROUNDTRIP Statistic::one_relation_more(); # else if (roundtrip) { expected_order.append(rel); container->set_updated(); roundtrip = FALSE; } } # endif #endif Lex::finish_line(); comment = Lex::get_comments(comment); description = Lex::get_description(description); #ifdef ROUNDTRIP if (roundtrip) { if (rel->visibility() != visibility) { rel->set_Visibility(visibility); container->set_updated(); } if (rel->isReadOnly() != constp) { rel->set_isReadOnly(constp); container->set_updated(); } if (rel->isClassMember() != staticp) { rel->set_isClassMember(staticp); container->set_updated(); } if (rel->isCppMutable() != mutablep) { rel->set_isCppMutable(mutablep); container->set_updated(); } if (rel->isVolatile() != volatilep) { rel->set_isVolatile(volatilep); container->set_updated(); } } else { #endif rel->set_Visibility(visibility); if (constp) rel->set_isReadOnly(TRUE); if (staticp) rel->set_isClassMember(TRUE); if (mutablep) rel->set_isCppMutable(TRUE); if (volatilep) rel->set_isVolatile(TRUE); #ifdef ROUNDTRIP } #endif Q3CString decl; if (typeform != "${type}") { // array & modified are empty, pretype is empty ? decl = CppSettings::relationDecl(TRUE, "*"); int index = typeform.find("<"); // cannot be -1 Q3CString st = typeform.left(index); Q3CString st_uml = CppSettings::umlType(st); #ifdef ROUNDTRIP if (roundtrip) { if (st_uml.isEmpty()) st_uml = st; if (neq(rel->stereotype(), st_uml)) { rel->set_Stereotype(st_uml); container->set_updated(); } } else #endif rel->set_Stereotype((st_uml.isEmpty()) ? st : st_uml); int index2; if ((index2 = decl.find("<${type}>")) == -1) { decl = " ${comment}${static}${mutable}${volatile}${const}${stereotype}<${type}> ${name}${value};"; index2 = decl.find("<${type}>"); } decl.replace(index2, 9, typeform.mid(index)); } else { if (!array.isEmpty()) { #ifdef ROUNDTRIP if (roundtrip) { if (neq(rel->multiplicity(), array)) { rel->set_Multiplicity(array); container->set_updated(); } } else #endif rel->set_Multiplicity(array); } decl = CppSettings::relationDecl(modifier != "*", array); int index; if (!pretype.isEmpty() && ((index = decl.find("${type}")) != 0)) decl.insert(index,(const char*)( pretype + " ")); if ((modifier == "&") && ((index = decl.find("${type}")) != 0)) decl.insert(index + 7, " &"); } if (! value.isEmpty()) { int index = decl.find("${value}"); if (index != -1) decl.insert(index + 2, "h_"); #ifdef ROUNDTRIP if (roundtrip) { if (!staticp) { Q3CString v = rel->defaultValue(); if (!v.isEmpty() && (((const char *) v)[0] == '=')) v = v.mid(1); if (nequal(v, value)) { rel->set_DefaultValue(value); container->set_updated(); } } } else #endif rel->set_DefaultValue(value); } #ifdef ROUNDTRIP if (roundtrip) { if (neq(rel->cppDecl(), decl)) { rel->set_CppDecl(decl); container->set_updated(); } if (decl.find("${description}") != -1) { if (nequal(rel->description(), description)) { rel->set_Description(description); container->set_updated(); } } else if (nequal(rel->description(), Lex::simplify_comment(comment))) { rel->set_Description(comment); // comment was set container->set_updated(); } // role name is the right one return TRUE; } #endif rel->set_CppDecl(decl); if (!comment.isEmpty()) rel->set_Description((decl.find("${description") != -1) ? description : Lex::simplify_comment(comment)); return rel->set_RoleName(name); }
Q3CString UmlPackage::file_path(const Q3CString & f) { if (!dir.read) { dir.file = javaDir(); if (! RootDirRead) { RootDirRead = TRUE; RootDir = JavaSettings::rootDir(); if (!RootDir.isEmpty() && // empty -> error QDir::isRelativePath(RootDir)) { QFileInfo f(getProject()->supportFile()); QDir d(f.dirPath()); RootDir = d.filePath(RootDir); } } QDir d_root(RootDir); if (dir.file.isEmpty()) dir.file = RootDir; else if (QDir::isRelativePath(dir.file)) dir.file = d_root.filePath(dir.file); if (dir.file.isEmpty()) { UmlCom::trace(Q3CString("<font color=\"red\"><b><b> The generation directory " "must be specified for the package<i> ") + name() + "</i>, edit the <i> generation settings</i> (tab 'directory') " "or edit the package (tab 'Java')</b></font><br>"); UmlCom::bye(n_errors() + 1); UmlCom::fatal_error("UmlPackage::file_path"); } dir.read = TRUE; } QDir d(dir.file); if (! d.exists()) { // create directory including the intermediates Q3CString s = dir.file; int index = 0; QChar sep = QDir::separator(); if (sep != '/') { while ((index = s.find(sep, index)) != -1) s.replace(index++, 1, "/"); } s = QDir::cleanDirPath(s) + "/"; index = s.find("/"); int index2; while ((index2 = s.find("/", index + 1)) != -1) { Q3CString s2 = s.left(index2); QDir sd(s2); if (!sd.exists()) { if (!sd.mkdir(s2)) { UmlCom::trace(Q3CString("<font color=\"red\"><b> cannot create directory <i>") + s2 + "</i></b></font><br>"); UmlCom::bye(n_errors() + 1); UmlCom::fatal_error("UmlPackage::file_path"); } } index = index2; } } return Q3CString(d.filePath(f).toAscii().constData()) + Q3CString(".") + JavaSettings::sourceExtension(); }
void UmlClass::write(QTextOStream & f, bool with_formals, BooL * is_template, const Q3ValueList<UmlActualParameter> & actuals) { if (context.findRef(this) == -1) { if (parent()->kind() == aClass) { if (context.findRef((UmlClass *) parent()) == -1) { // parent cannot have formals, but may have actuals ((UmlClass *) parent())->write(f, FALSE, 0, actuals); f << "::"; } } else { UmlArtifact * cp = associatedArtifact(); Q3CString nasp = ((UmlPackage *) ((cp != 0) ? (UmlItem *) cp : (UmlItem *) this)->package()) ->cppNamespace(); if (CppSettings::isForceNamespacePrefixGeneration() || (nasp != UmlArtifact::generation_package()->cppNamespace())) f << nasp << "::"; } } Q3CString s; if (isCppExternal()) { s = cppDecl(); int index = s.find('\n'); s = (index == -1) ? s.stripWhiteSpace() : s.left(index).stripWhiteSpace(); if ((index = s.find("${name}")) != -1) s.replace(index, 7, name()); else if ((index = s.find("${Name}")) != -1) s.replace(index, 7, capitalize(name())); else if ((index = s.find("${NAME}")) != -1) s.replace(index, 7, name().upper()); else if ((index = s.find("${nAME}")) != -1) s.replace(index, 7, name().lower()); } else s = name(); // true_name if (! s.isEmpty()){ f << s; if (is_template != 0) *is_template = (s.at(s.length() - 1) == '>'); } else if (is_template != 0) *is_template = FALSE; if (with_formals) { Q3ValueList<UmlFormalParameter> formals = this->formals(); if (! formals.isEmpty()) { const char * sep = "<"; Q3ValueList<UmlFormalParameter>::ConstIterator it; for (it = formals.begin(); it != formals.end(); ++it) { f << sep << (*it).name(); sep = ", "; } f << '>'; if (is_template != 0) *is_template = TRUE; } } else if (!actuals.isEmpty()) { Q3ValueList<UmlActualParameter>::ConstIterator ita; BooL need_space = FALSE; bool used = FALSE; for (ita = actuals.begin(); ita != actuals.end(); ++ita) { if ((*ita).superClass() == this) { used = TRUE; (*ita).generate(f, need_space); } } if (used) { if (need_space) f << " >"; else f << '>'; if (is_template != 0) *is_template = TRUE; } } }
void UmlArtifact::generate() { if (! managed) { managed = TRUE; if (stereotype() == "text") { generate_text(); return; } else if (stereotype() != "source") return; package_of_generated_artifact = package(); const Q3CString def = idlSource(); if (def.isEmpty()) return; const Q3CString & name = this->name(); UmlPackage * pack = package(); Q3CString path = pack->path(name); Q3CString mod_start; Q3CString mod_end; Q3CString mod = pack->idlModule(); if (! mod.isEmpty()) { int index = 0; int index2; Q3CString closed = "\n}; // module "; while ((index2 = mod.find(':', index)) != -1) { Q3CString mo = mod.mid(index, index2 - index); mod_start += Q3CString("module ") + mo + " {\n\n"; closed += mo; mod_end = closed + "\n" + mod_end; closed += "::"; mod.replace(index2, 2, "_"); index = index2 + 1; } mod_start += Q3CString("module ") + mod.mid(index) + " {\n\n"; closed += mod.mid(index); mod_end = closed + "\n" + mod_end; } UmlCom::message(name); if (verbose()) UmlCom::trace(Q3CString("<hr><font face=helvetica>Generate code for <i> ") + name + "</i> in <i>" + path + "</i></font><br>"); else set_trace_header(Q3CString("<font face=helvetica>Generate code for <i> ") + name + "</i> in <i>" + path + "</i></font><br>"); #if 0 // compute dependencies Q3PtrList<CppRefType> dependencies; #endif const Q3PtrVector<UmlClass> & cls = associatedClasses(); unsigned n = cls.count(); unsigned index; #if 0 for (index = 0; index != n; index += 1) cls[index]->compute_dependencies(dependencies); #endif // generate source file QByteArray file; QTextOStream f(&file); const char * p = def; const char * pp = 0; for (;;) { if (*p == 0) { if (pp == 0) break; // comment management done p = pp; pp = 0; if (*p == 0) break; } if (*p == '@') manage_alias(p, f); else if (*p != '$') f << *p++; else if (!strncmp(p, "${comment}", 10)) manage_comment(p, pp); else if (!strncmp(p, "${description}", 14)) manage_description(p, pp); else if (!strncmp(p, "${name}", 7)) { p += 7; f << name; } else if (!strncmp(p, "${Name}", 7)) { p += 7; f << capitalize(name); } else if (!strncmp(p, "${NAME}", 7)) { p += 7; f << name.upper(); } else if (!strncmp(p, "${nAME}", 7)) { p += 7; f << name.lower(); } else if (!strncmp(p, "${module}", 9)) { p += 9; f << mod; } else if (!strncmp(p, "${MODULE}", 9)) { p += 9; f << mod.upper(); } else if (!strncmp(p, "${includes}", 11)) { p += 11; /*if (!incl_computed) { incl_computed = TRUE; CppRefType::compute(dependencies, hdef, srcdef, h_incl, decl, incl, this); } if (!incl.isEmpty()) { f << incl; if (*p != '\n') f << '\n'; } else*/ if (*p == '\n') p += 1; } else if (!strncmp(p, "${definition}", 13)) { p += 13; for (index = 0; index != n; index += 1) cls[index]->generate(f); if (*p == '\n') p += 1; } else if (!strncmp(p, "${module_start}", 15)) { p += 15; if (!mod_start.isEmpty()) f << mod_start; if (*p == '\n') p += 1; } else if (!strncmp(p, "${module_end}", 13)) { p += 13; if (!mod_end.isEmpty()) f << mod_end; if (*p == '\n') p += 1; } else // strange f << *p++; } f << '\000'; if (must_be_saved(path, file)) { write_trace_header(); FILE * fp; if ((fp = fopen((const char *) path, "wb")) == 0) { write_trace_header(); UmlCom::trace(Q3CString("<font color=\"red\"><b><i> ") + name + " : </i> cannot open <i> " + path + "</i>, edit the <i> generation settings</i> (tab directory) or the <i>" + pack->name() + "</i> Idl directory specification</b></font><br>"); incr_error(); } else { fputs((const char *) file, fp); fclose(fp); } } else if (get_trace_header().isEmpty()) UmlCom::trace(Q3CString("<font face=helvetica><i> ") + path + "</i> not modified</font><br>"); } }
bool UmlOperation::new_one(Class * container, aVisibility visibility, bool finalp, bool abstractp, bool staticp, Q3CString comment, Q3CString description) { // 'function' was read, it is followed by : // ['&'] name'(' {'array' | <classname>] ['&'] '$'<varname> ['=' <value>]}* ')' '{' ... '}' Q3CString s = Lex::read_word(); bool refp; if (s == "&") { refp = TRUE; s = Lex::read_word(); } else refp = FALSE; if (s.isEmpty()) { Lex::premature_eof(); return FALSE; } Q3CString name = s; #ifdef TRACE QLOG_INFO() <<"OPERATION '" << name << "'\n"; #endif s = Lex::read_word(); if (s != "(") { Lex::syntax_error("'(' expected rather than '" + s + "'"); return FALSE; } UmlClass * cl = container->get_uml(); UmlOperation * op; #ifndef REVERSE if (visibility == PrivateVisibility) op = 0; else #endif { op = UmlBaseOperation::create(cl, name); if (op == 0) { PhpCatWindow::trace(Q3CString("<font face=helvetica><b>cannot add operation <i>") + name + "</i> in <i>" + cl->name() + "</i></b></font><br>"); return FALSE; } #ifdef REVERSE Statistic::one_operation_more(); #endif } Q3CString def; if (op != 0) { op->set_Visibility(visibility); if (staticp) op->set_isClassMember(TRUE); if (finalp) op->set_isPhpFinal(TRUE); def = PhpSettings::operationDef(); int index; if (((index = def.find("${(}")) == -1) || (def.find("${)}", index + 4) == -1) || ((index = def.find("${name}")) == -1) || (def.find("${body}") == -1)) { // use a definition where ${body] is not indented def = " ${comment}${final}${visibility}${abstract}${static}function ${name}${(}${)}\n{\n ${body}}\n"; index = def.find("${name}"); } if (refp) def.insert(index, "&"); if ((name == cl->name()) || (name == "__construct")) { // constructor, remove useless ${} if ((index = def.find("${static}")) != -1) def.remove(index, 9); if ((index = def.find("${final}")) != -1) def.remove(index, 8); if ((index = def.find("${abstract}")) != -1) def.remove(index, 11); } if (abstractp) { op->set_isAbstract(TRUE); def = def.left(def.find("${)}") + 4) + ";"; } } // parameters unsigned rank = 0; UmlParameter param; while (read_param(container, rank, param, def, op == 0)) { if ((op != 0) && ! op->addParameter(rank++, param)) { PhpCatWindow::trace(Q3CString("<font face=helvetica><b>cannot add param <i>") + name + "</i> in <i>" + cl->name() + "</i></b></font><br>"); #ifdef TRACE QLOG_INFO() <<"ERROR cannot add param '" << param.name << '\n'; #endif return FALSE; } } s = Lex::read_word(); if (s.isEmpty()) { Lex::premature_eof(); return FALSE; } // definition if (abstractp || (cl->stereotype() == "interface")) { if (s != ";") { Lex::error_near(s); return FALSE; } #ifdef REVERSE if (op != 0) op->set_PhpBody(0); #endif } else if (s != "{") { Lex::error_near(s); return FALSE; } else { Lex::mark(); // goto the end of the body char c; int level = 1; // '{' already read for (;;) { if ((c = Lex::read_word_bis()) == 0) return FALSE; else if (c == '{') level += 1; else if ((c == '}') && (--level == 0)) break; } #ifdef REVERSE if (op != 0) { Q3CString e = Lex::region(); e.truncate(e.length() - 1); // remove } // remove fist \n if (*((const char *) e) == '\n') e.remove(0, 1); // remove last spaces and tabs int ln = e.length(); while (ln && ((e[ln - 1] == ' ') || (e[ln - 1] == '\t'))) ln -= 1; e.truncate(ln); op->set_PhpBody(e); op->set_PhpContextualBodyIndent(FALSE); } #endif } if ((op != 0) && (def != op->phpDecl())) op->set_PhpDecl(def); Lex::clear_comments(); // params & body comments Lex::finish_line(); if ((op != 0) && !comment.isEmpty()) { s = (def.find("${description}") != -1) ? description : comment; UmlTypeSpec t; int index1; if (! (t.explicit_type = value_of(s, "@return", index1)).isEmpty()) { op->set_ReturnType(t); s.replace(index1, t.explicit_type.length(), "${type}"); } Q3ValueList<UmlParameter> l = op->params(); unsigned nparams = l.count(); if (nparams != 0) { Q3CString varname; int index2; char xn[16]; index1 = 0; rank = 0; while (!((t.explicit_type = value_of(s, "@param", index1, varname, index2)) .isEmpty())) { if (varname.isEmpty() || (varname[0] != '$')) { if (rank < nparams) { UmlParameter & p = l[rank]; p.type = t; op->replaceParameter(rank, p); } } else { varname = varname.mid(1); Q3ValueList<UmlParameter>::Iterator it; for (it = l.begin(), rank = 0; it != l.end(); ++it, rank += 1) { if ((*it).name == varname) { (*it).type = t; op->replaceParameter(rank, *it); sprintf(xn, "${p%d}", rank); s.replace(index2, varname.length() + 1, xn); break; } } } sprintf(xn, "${t%d}", rank++); s.replace(index1, t.explicit_type.length(), xn); } } op->set_Description(s); } return TRUE; }