示例#1
0
static bool rename(QCString & s, bool java, bool javasettings)
{
  static const struct {
    const char * o;
    const char * n;
    bool java_only;
  } T[] = {
    { "enumDecl", "enumPatternDecl", FALSE },
    { "set_EnumDecl", "set_EnumPatternDecl", FALSE },
    { "enumItemDecl", "enumPatternItemDecl", FALSE },
    { "set_EnumItemDecl", "set_EnumPatternItemDecl", FALSE },
    { "enumItemCase", "enumPatternItemCase", FALSE },
    { "set_EnumItemCase", "set_EnumPatternItemCase", FALSE },
    
    { "setJavaEnumDeclCmd", "setJavaEnumPatternDeclCmd", FALSE },
    { "setJavaEnumItemDeclCmd", "setJavaEnumPatternItemDeclCmd", FALSE },
    { "setJavaEnumItemCaseCmd", "setJavaEnumPatternItemCaseCmd", FALSE },
    
    { "_setJavaEnumDeclCmd", "_setJavaEnumPatternDeclCmd", TRUE },
    { "_setJavaEnumItemDeclCmd", "_setJavaEnumPatternItemDeclCmd", TRUE },
    { "_setJavaEnumItemCaseCmd", "_setJavaEnumPatternItemCaseCmd", TRUE },
    
    { "_enum_decl", "_enum_pattern_decl", FALSE },
    { "_enum_item_decl", "_enum_pattern_item_decl", FALSE },
    { "_enum_item_case", "_enum_pattern_item_case", FALSE }
  };
  int t_index;
  bool changed = FALSE;
  
  for (t_index = 0; t_index != sizeof(T)/sizeof(T[0]); t_index += 1) {
    if (!T[t_index].java_only || java) {
      QCString o = T[t_index].o;
      
      if (!javasettings)
	o = ((java) ? "JavaSettings." : "JavaSettings::") + o;
      
      int o_len = o.length();
      QCString n = T[t_index].n;
      
      if (!javasettings)
	n = ((java) ? "JavaSettings." : "JavaSettings::") + n;
      
      int n_len = n.length();
      int index = 0;
      
      while ((index = s.find(o, index)) != -1) {
	if (((index == 0) || is_sep(s[index - 1])) &&
	    is_sep(s[index + o_len])) {
	  s.replace(index, o_len, n);
	  index += n_len;
	  changed = TRUE;
	}
	else
	  index += 1;
      }
    }
  }

  return changed;
}
示例#2
0
void UmlItem::replace_alias(QCString & s) {
  int index = 0;
  
  while ((index = s.find("@{", index)) != -1) {
    int index2 = s.find('}', index + 2);
    
    if (index2 == -1)
      return;
    
    UmlBaseItem * obj = this;
    QCString key = s.mid(index + 2, index2 - index - 2);
    QCString 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;
      }
    }
  }
}
示例#3
0
void UmlClassItem::remove_comments(QCString & s)
{
  int index1 = 0;
  
  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;
    }
  }
}
示例#4
0
//----------------------------------------------------------------------------
// some quasi intelligent brief description abbreviator :^)
QCString abbreviate(const char *s,const char *name)
{
  QCString scopelessName=name;
  int i=scopelessName.findRev("::");
  if (i!=-1) scopelessName=scopelessName.mid(i+2);
  QCString result=s;
  result=result.stripWhiteSpace();
  // strip trailing .
  if (!result.isEmpty() && result.at(result.length()-1)=='.') 
    result=result.left(result.length()-1);

  // strip any predefined prefix
  QStrList &briefDescAbbrev = Config_getList("ABBREVIATE_BRIEF");
  const char *p = briefDescAbbrev.first();
  while (p)
  {
    QCString s = p;
    s.replace(QRegExp("\\$name"), scopelessName);  // replace $name with entity name
    s += " ";
    stripWord(result,s);
    p = briefDescAbbrev.next();
  }

  // capitalize first word
  if (!result.isEmpty())
  {
    int c=result[0];
    if (c>='a' && c<='z') c+='A'-'a';
    result[0]=c;
  }
  return result;
}
示例#5
0
void UmlClass::write(QTextOStream & f) {
  if (isJavaExternal()) {
    QCString 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;
    QCString 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()) {
      QCString 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();
  }
}
示例#6
0
QCString replace(QCString f, QCString k, QCString v)
{
  int index = f.find(k);

  return (index != -1)
    ? f.replace(index, k.length(), v)
    : f;
}
示例#7
0
void UmlOperation::set_java(const char * return_form,
			    const char * params, QCString body,
			    bool inlinep) {
  QCString s = JavaSettings::operationDef();
  int index = s.find("${type}");
  
  s.replace(index, 7, return_form);
  s.insert(s.find("${)}", index), params);
  
  if (inlinep) {
    s.replace(s.findRev("${body}"), 7, body);
    set_JavaDef(s);
  }
  else {
    set_JavaDef(s);
    set_JavaBody(body);
  }
}
示例#8
0
void UmlClassItem::remove_arrays(QCString & 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, " ");
  }
}
示例#9
0
QCString legalName(QCString s)
{
  for (unsigned index = 0; index != s.length(); index += 1) {
    char c = s.at(index);
    
    if ((c != '_') && 
	!((c >= 'a') && (c <= 'z')) &&
        !((c >= 'A') && (c <= 'Z')) &&
	!((c >= '0') && (c <= '9'))) {
      s.replace(index, 1, "__");
      index += 1;
    }
  }

  return s;
}
    void JSObjectProxy::addSlotBinding( const QCString &name, KJS::ExecState *exec, KJS::Object &object ) {
        // Lookup and bind slot
        QMetaObject * mo = obj->metaObject();
        int slotid = mo->findSlot( name.data(), true );
        if ( slotid == -1 )
            return ;

        const QMetaData *md = mo->slot( slotid, true );
        if ( md->access != QMetaData::Public )
            return ;

        // Find signature
        int id = Bindings::JSSlotUtils::findSignature( name );
        //    kdDebug( 80001 )<<"JSObjectProxy::addSlotBinding()::slot:"<<name<<" id:"<<id<<endl;
        if ( id < 0 )
            return ;

        QCString jsname = name;
        jsname.detach();
        jsname.replace( QRegExp( "\\([^\\)]*\\)" ), "" );

        // Find the return type, we only care if it is a pointer type
        const QUMethod *m = md->method;
        const char *retclass = 0;
        QCString ptr( "ptr" );

        if ( m->count && ( m->parameters->inOut == QUParameter::Out )
                && ( ptr == m->parameters->type->desc() ) ) {
            retclass = ( const char * ) m->parameters->typeExtra;
            //  kdDebug(80001) << "Return type is a pointer, type " << retclass << endl;
        }

        // Create the Imp
        JSObjectProxyImp *imp = new JSObjectProxyImp( exec, JSObjectProxyImp::MethodSlot,
                                retclass ? retclass : "", id, name, this );

        if ( !object.hasProperty( exec, KJS::Identifier( jsname ) ) ) {
            // The identifier is unused
            object.put( exec, KJS::Identifier( jsname.data() ), KJS::Object( imp ) );
        } else {
            // The identifier has already been used
            QString s( name );
            QCString cs = QString( "%1%2" ).arg( jsname ).arg( s.contains( ',' ) + 1 ).ascii();
            //kdDebug(80001) << "Method " << jsname << " exists, using " << cs << " for " << s << endl;
            object.put( exec, KJS::Identifier( cs.data() ), KJS::Object( imp ) );
        }
    }
示例#11
0
void MonitorWindow::save()
{
    QString s = QFileDialog::getSaveFileName ("sim.log", QString::null, this);
    if (s.isEmpty()) return;
    QFile f(s);
    if (!f.open(IO_WriteOnly)){
        QMessageBox::warning(this, i18n("Error"), i18n("Can't create file %1") .arg(s));
        return;
    }
    QCString t;
    if (edit->hasSelectedText()){
        t = unquoteText(edit->selectedText()).local8Bit();
    }else{
        t = unquoteText(edit->text()).local8Bit();
    }
#if defined(WIN32) || defined(__OS2__)
    t.replace(QRegExp("\n"),"\r\n");
#endif
    f.writeBlock(t, t.length());
}
示例#12
0
QString Namespace::namespacify(QCString s, bool local) {
  QString r;
  int index = s.find("::");
  
  if (index == 0)
    r = ((const char *) s) + 2;
  else {
    if (index != -1) {
      QMap<QCString,QCString>::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;
}
示例#13
0
void CppRefType::compute(QList<CppRefType> & dependencies,
			 const QCString & hdef, const QCString & srcdef,
			 QCString & h_incl,  QCString & decl, QCString & src_incl,
			 UmlArtifact * who)
{
  UmlPackage * pack = who->package();
  QCString hdir;
  QCString srcdir;
  
  if (CppSettings::isRelativePath()) {
    QCString empty;
    
    hdir = pack->header_path(empty);
    srcdir = pack->source_path(empty);
  }
  else if (CppSettings::isRootRelativePath())
    hdir =  srcdir = UmlPackage::rootDir();
  
  // aze.cpp includes aze.h
  src_incl += "#include \"";
  if (CppSettings::includeWithPath())
    src_incl += pack->header_path(who->name(), srcdir);
  else {
    src_incl += who->name();
    src_incl += '.';
    src_incl += CppSettings::headerExtension();
  }
  src_incl += "\"\n";
  h_incl = "";	// to not be QCString::null
  decl = "";	// to not be QCString::null
  
  CppRefType * ref;
  
  for (ref = dependencies.first(); ref != 0; ref = dependencies.next()) {
    UmlClass * cl = (ref->type.type)
      ? ref->type.type
      : UmlBaseClass::get(ref->type.explicit_type, 0);
    bool included = ref->included;
    QCString hform;	// form in header
    QCString srcform;	// form in source
    
    if (cl == 0) {
      QCString in = CppSettings::include(ref->type.explicit_type);
      
      if (!in.isEmpty()) 
	hform = srcform = in + '\n';
      else
	// doesn't know what it is
	continue;
    }
    else if (cl->isCppExternal()) {
      hform = cl->cppDecl();
      
      int index;
      
      if ((index = hform.find('\n')) == -1)
	// wrong form
	continue;
      
      hform = hform.mid(index + 1) + '\n';
      
      for (;;) {
	if ((index = hform.find("${name}")) != -1)
	  hform.replace(index, 7, cl->name());
	else if ((index = hform.find("${Name}")) != -1)
	  hform.replace(index, 7, capitalize(cl->name()));
	else if ((index = hform.find("${NAME}")) != -1)
	  hform.replace(index, 7, cl->name().upper());
	else if ((index = hform.find("${nAME}")) != -1)
	  hform.replace(index, 7, cl->name().lower());
	else
	  break;
      }
      srcform = hform;
    }
    else {
      QCString st = cl->cpp_stereotype();	
      
      if ((st == "enum") || (st == "typedef"))
	included = TRUE;
      
      UmlArtifact * art = cl->associatedArtifact();
      
      if (art != 0) {
	if (art == who)
	  // don't include itself
	  continue;
	if (CppSettings::includeWithPath()) {
	  UmlPackage * p = art->package();
	  
	  hform = "#include \"" + p->header_path(art->name(), hdir) + "\"\n";
	  srcform = "#include \"" + p->header_path(art->name(), srcdir) + "\"\n";
	}
	else
	  srcform = hform = "#include \"" + art->name() + '.' +
	    CppSettings::headerExtension() + "\"\n";
      }
      else if (cl->parent()->kind() != aClass) {
	write_trace_header();
	UmlCom::trace(QCString("&nbsp;&nbsp;&nbsp;&nbsp;<font color=\"red\"><b> class<i> ") + cl->name() +
		      "</i> referenced but does not have associated <i>artifact</i></b></font><br>");
	incr_warning();
	continue;
      }
    }
    
    if (included) {
      // #include must be placed in the header file
      if ((h_incl.find(hform) == -1) && (hdef.find(hform) == -1))
	h_incl += hform;
    }
    else if ((cl != 0) &&
	     (cl->parent()->kind() != aClass)) {	// else too complicated
      // #include useless in header file, place it in the source file
      if ((src_incl.find(srcform) == -1) && (h_incl.find(hform) == -1) &&
	  (hdef.find(hform) == -1) && (srcdef.find(srcform) == -1))
	src_incl += srcform;
      
      if (!cl->isCppExternal()) {
	// header file must contains the declaration
	hform = cl->decl();
	
	if (decl.find(hform) == -1)
	  decl += hform;
	
	if ((cl->associatedArtifact() == 0) &&
	    (cl->parent()->kind() != aClass)) {
	  write_trace_header();
	  UmlCom::trace(QCString("&nbsp;&nbsp;&nbsp;&nbsp;<font color=\"red\"><b> class<i> ") + cl->name() +
			"</i> referenced but does not have associated <i>artifact</i></b></font><br>");
	  incr_warning();
	}
      }
    }
    else if (!hform.isEmpty()) {
      // have the #include form but does not know if it is a class or other,
      // generate the #include in the header file EXCEPT if the #include is
      // already in the header/source file to allow to optimize the generated
      // code
      if ((src_incl.find(srcform) == -1) && (h_incl.find(hform) == -1) &&
	  (hdef.find(hform) == -1) && (srcdef.find(srcform) == -1))
	h_incl += hform;
    }
  }
}
示例#14
0
QString KXFace::fromImage(const QImage &image)
{
    if(image.isNull())
        return QString::null;

    QImage scaledImg = image.smoothScale(48, 48);
    QByteArray ba;
    QBuffer buffer(ba);
    buffer.open(IO_WriteOnly);
    scaledImg.save(&buffer, "XBM");
    QString xbm(ba);
    xbm.remove(0, xbm.find("{") + 1);
    xbm.truncate(xbm.find("}"));
    xbm.remove(" ");
    xbm.remove(",");
    xbm.remove("0x");
    xbm.remove("\n");
    xbm.truncate(576);
    QCString tmp = QCString(xbm.latin1());
    uint len = tmp.length();
    for(uint i = 0; i < len; ++i)
    {
        switch(tmp[i])
        {
            case '1':
                tmp[i] = '8';
                break;
            case '2':
                tmp[i] = '4';
                break;
            case '3':
                tmp[i] = 'c';
                break;
            case '4':
                tmp[i] = '2';
                break;
            case '5':
                tmp[i] = 'a';
                break;
            case '7':
                tmp[i] = 'e';
                break;
            case '8':
                tmp[i] = '1';
                break;
            case 'A':
            case 'a':
                tmp[i] = '5';
                break;
            case 'B':
            case 'b':
                tmp[i] = 'd';
                break;
            case 'C':
            case 'c':
                tmp[i] = '3';
                break;
            case 'D':
            case 'd':
                tmp[i] = 'b';
                break;
            case 'E':
            case 'e':
                tmp[i] = '7';
                break;
        }
        if(i % 2)
        {
            char t = tmp[i];
            tmp[i] = tmp[i - 1];
            tmp[i - 1] = t;
        }
    }
    tmp.replace(QRegExp("(\\w{12})"), "\\1\n");
    tmp.replace(QRegExp("(\\w{4})"), "0x\\1,");
    len = tmp.length();
    char *fbuf = (char *)malloc(len + 1);
    strncpy(fbuf, (const char *)tmp, len);
    fbuf[len] = '\0';
    if(!(status = setjmp(comp_env)))
    {
        ReadFace(fbuf);
        GenFace();
        CompAll(fbuf);
    }
    QString ret(fbuf);
    free(fbuf);

    return ret;
}
示例#15
0
void UmlOperation::set_cpp(const char * return_form_or_inherit,
			   const char * params, QCString body,
			   bool inlinep, const char * if_def,
			   const char * end_if) {
  if (*return_form_or_inherit == ':') {
    // inherit
    if (inlinep) {
      QCString s = remove_throw(CppSettings::operationDecl());
      int index = s.find("${)}");
      
      s.resize(index + 5);
      s.insert(index, params);
      s.append(" ");
      s.append(return_form_or_inherit);
      if (!body.isEmpty()) {
	s.append(" {\n  ");
	s.append(body);
	s.append("}\n");
      }
      else
	s.append(" {\n}\n");
      conditional(s, if_def, end_if);
      set_CppDecl(s);
      
      set_CppDef("");
    }
    else {
      QCString s = remove_throw(CppSettings::operationDecl());
      int index = s.find("${)}");
      
      s.resize(index + 5);
      s.insert(index, params);
      s.append(";");
      conditional(s, if_def, end_if);
      set_CppDecl(s);
      
      s = remove_throw(CppSettings::operationDef());
      index = s.find("${)}");
      s.resize(index + 5);
      s.insert(index, params);
      s.append(" ");
      s.append(return_form_or_inherit);
      if (!body.isEmpty()) {
	s.append(" {\n  ");
	s.append(body);
	s.append("}\n");
      }
      else
	s.append(" {\n}\n");
      conditional(s, if_def, end_if);
      set_CppDef(s);
    }
  }
  else {
    // return
    if (inlinep) {
      QCString s = remove_throw(CppSettings::operationDecl());
      int index = s.find("${type}");
      
      s.replace(index, 7, return_form_or_inherit);
      s.insert(s.find("${)}", index), params);
      s.resize(s.findRev(";") + 1);
      if (!body.isEmpty()) {
	s.append(" {\n  ");
	s.append(body);
	s.append("}\n");
      }
      else
	s.append(" {\n}\n");
      conditional(s, if_def, end_if);
      set_CppDecl(s);
      
      set_CppDef("");
    }
    else {
      QCString s = remove_throw(CppSettings::operationDecl());
      int index = s.find("${type}");
      
      s.replace(index, 7, return_form_or_inherit);
      s.insert(s.find("${)}", index), params);
      conditional(s, if_def, end_if);
      set_CppDecl(s);
      
      s = remove_throw(CppSettings::operationDef());
      index = s.find("${type}");
      s.replace(index, 7, return_form_or_inherit);
      s.insert(s.find("${)}", index), params);
      conditional(s, if_def, end_if);
      set_CppDef(s);
      
      set_CppBody(body);
    }
  }
}
示例#16
0
// from a form 'generic<...C...> var' where C is a class
bool UmlRelation::new_one(Class * container, const QCString & name,
			  UmlClass * type, QCString type_def,
			  QCString genericname,
			  aVisibility visibility, bool staticp,
			  bool constp, bool transientp, bool volatilep,
			  const QCString & array, const QCString & value,
			  QCString comment, QCString description,
			  QCString annotation
#ifdef ROUNDTRIP
			  , bool roundtrip, QList<UmlItem> & expected_order
#endif
			)
{
#ifdef TRACE
  cout << "RELATION '" << name << "' from '" << cl->Name() << "' to '" << type->Name()
    << "' array '" << array << "'\n";
#endif
  
  if (
#ifdef REVERSE
      container->from_libp() &&
#endif
      (visibility == PrivateVisibility)) {
    Lex::finish_line();
    Lex::clear_comments();
    return TRUE;
  }
  
  QCString st = JavaSettings::umlType(genericname);
  
  if (st.isEmpty())
    st = genericname;
  
  UmlClass * cl = container->get_uml();
  UmlRelation * rel;
  
#ifdef ROUNDTRIP
  bool created;
  
  if (!roundtrip ||
      ((rel = search_rel(container, name, type, st)) == 0)) {
#endif
  rel = UmlBaseRelation::create(aDirectionalAssociation, cl, type);
  
  if (rel == 0) {
    JavaCatWindow::trace(QCString("<font face=helvetica><b>cannot add relation <i>")
			 + name + "</i> in <i>" + cl->name() + "</i> to <i>"
			 + type->name() + "</i></b></font><br>");  
    return FALSE;
  }
    
#ifdef REVERSE
# ifndef ROUNDTRIP
    Statistic::one_relation_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);
  
  QCString decl = JavaSettings::relationDecl(array);
  
  type_def.replace(0, genericname.length(), "${stereotype}");
  decl.replace(decl.find("${type}"), 7, type_def);
    
  
#ifdef ROUNDTRIP
  if (roundtrip && !created) {
    if (rel->visibility() != visibility) {
      rel->set_Visibility(visibility);
      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();
    }
  
    if (rel->isReadOnly() != constp) {
      rel->set_isReadOnly(constp);
      container->set_updated();
    }
    
    if (rel->isJavaTransient() != transientp) {
      rel->set_isJavaTransient(transientp);
      container->set_updated();
    }
    
    if (rel->isVolatile() != volatilep) {
      rel->set_isVolatile(volatilep);
      container->set_updated();
    }
    
    if (rel->isClassMember() != staticp) {
      rel->set_isClassMember(staticp);
      container->set_updated();
    }
    
    if (neq(rel->multiplicity(), array)) {
      rel->set_Multiplicity(array);
      container->set_updated();
    }
    
    if (neq(rel->defaultValue(), value)) {
      rel->set_DefaultValue(value);
      container->set_updated();
    }
    
    if (nequal(rel->javaAnnotations(), annotation)) {
      rel->set_JavaAnnotations(annotation);
      container->set_updated();
    }
    
    if (neq(rel->stereotype(), st) &&
	(rel->stereotype().isEmpty() ||
	 (JavaSettings::relationAttributeStereotype(rel->stereotype()) != st))) {
      rel->set_Stereotype(st);
      container->set_updated();
    }
    
    if (neq(rel->javaDecl(), decl)) {
      rel->set_JavaDecl(decl);
      container->set_updated();
    }
    
    // role name is the right one
    
    rel->set_usefull();
    expected_order.append(rel);
  }
  else {
#endif
  rel->set_Visibility(visibility);
  
  if (!comment.isEmpty())
    rel->set_Description((decl.find("${description}") != -1)
			 ? description : Lex::simplify_comment(comment));
  
  if (constp)
    rel->set_isReadOnly(TRUE);
  
  if (transientp)
    rel->set_isJavaTransient(TRUE);
  
  if (volatilep)
    rel->set_isVolatile(TRUE);
  
  if (staticp)
    rel->set_isClassMember(TRUE);
  
  if (!array.isEmpty())
    rel->set_Multiplicity(array);
  
  if (! value.isEmpty())
    rel->set_DefaultValue(value);
  
  if (! annotation.isEmpty())
    rel->set_JavaAnnotations(annotation);
  
  rel->set_Stereotype(st);
  
  rel->set_JavaDecl(decl);

  rel->set_RoleName(name);
  
#ifdef ROUNDTRIP
  if (roundtrip)
    expected_order.append(rel);
  }
#endif
  
  return TRUE;
}
示例#17
0
bool UmlAttribute::manage_enum_item(QCString name, UmlClass * cl
#ifdef ROUNDTRIP
				    , bool roundtrip,
				    QList<UmlItem> & expected_order
#endif
				    )
{   
  QCString comment = Lex::get_comments();
  QCString description = Lex::get_description();
  UmlAttribute * item = 0;	// initialize to avoid warning
#ifdef ROUNDTRIP
  Class * container = 0;	// initialize to avoid warning
  bool created = FALSE;		// initialize to avoid warning
#endif
  
  if (!Package::scanning()) {
#ifdef ROUNDTRIP
    container = cl->get_class();
    
    if (!roundtrip ||
	((item = search_attr(container, name)) == 0)) {
#endif
      if ((item = UmlBaseAttribute::create(cl, name)) == 0) {
	JavaCatWindow::trace(QCString("<font face=helvetica><b>cannot add enum item <i>")
			     + name + "</i> in <i>" + cl->name() 
			     + "</i></b></font><br>");  
	return FALSE;
      }
      
      item->set_Visibility(PublicVisibility);
#ifdef ROUNDTRIP
      if (roundtrip)
	container->set_updated();
    
      created = TRUE;
    }
#endif
  }
  
  Lex::mark();
  
  QCString aux;
  QCString s;
  
  if ((s = Lex::read_word()).isEmpty()) {
    if (! Package::scanning())
      Lex::premature_eof();
    return FALSE;
  }
  else if ((s == ";") || (s == "}")) {
    aux = Lex::region();
    Lex::unread_word(s);
  }
  else if (s == ",") {
    aux = Lex::region();
    Lex::finish_line();
    comment = Lex::get_comments(comment);
    description = Lex::get_description(description);
  }
  else if ((s == "(") || (s == "{")) {
    char c = UmlOperation::skip_expr(1);	// goes after opt init and body
    if (c == 0) {
      if (! Package::scanning())
	Lex::premature_eof();
      return FALSE;
    }
    // c is ',' or ';'
    if (c == ';')
      Lex::unread_word(";");
    aux = Lex::region();
  }
  else {
    if (! Package::scanning())
      Lex::error_near(s);
    return FALSE;
  }
  
  if (!Package::scanning()) {
    // here aux = opt init and body + final character , ; or }
    QCString decl = JavaSettings::enumItemDecl();
    int index;
    
    if ((decl.find("${name}") == -1) ||
	((index = decl.find("${value}")) == -1)) {
      decl = "  ${name}${value},${comment}";
      index = decl.find("${value}");
    }
    
    aux.resize(aux.length()); // remove , ; or }, warning resize count \000
    if (!aux.stripWhiteSpace().isEmpty())
      decl.replace(index, 8, aux);

#ifdef ROUNDTRIP
    if (roundtrip && !created) {
      if (decl.find("${description}") != -1) {
	if (nequal(item->description(), description)) {
	  item->set_Description(description);
	  container->set_updated();
	}
      }
      else if (nequal(item->description(), Lex::simplify_comment(comment))) {
	item->set_Description(comment); // comment was changed
	container->set_updated();
      }
      
      if (neq(item->javaDecl(), decl)) {
	item->set_JavaDecl(decl);
	container->set_updated();
      }
    
      item->set_usefull();
      
      expected_order.append(item);
    }
    else {
#endif
      if (!comment.isEmpty())
	item->set_Description((decl.find("${description}") != -1)
			      ? description : Lex::simplify_comment(comment));
      
      item->set_JavaDecl(decl);
      
#ifdef ROUNDTRIP
      if (roundtrip)
	expected_order.append(item);
    }
#endif
  }
    
  return TRUE;
}
示例#18
0
QCString UmlPackage::file_path(const QCString & f) {
  if (!dir.read) {
    dir.file = pythonDir();
    
    if (! RootDirRead) {
      RootDirRead = TRUE;
      RootDir = PythonSettings::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(QCString("<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 'Python')</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
    QCString s = dir.file;
    int index = 0;
    char 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) {
      QCString s2 = s.left(index2);
      QDir sd(s2);
      
      if (!sd.exists()) {
	if (!sd.mkdir(s2)) {
	  UmlCom::trace(QCString("<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 QCString(d.filePath(f)) + QCString(".") + 
    PythonSettings::sourceExtension();
}
示例#19
0
void SenderUI::slotSend() {
    QCString str = MultiLineEdit1->text().utf8();
    owarn << "sending: " << str.data() << "" << oendl;
    str = str.replace( QRegExp("\n"), "\r");
    ser->send( str );
}
示例#20
0
bool UmlAttribute::new_one(Class * container, const QCString & name,
			   const QCString & type, const QCString & modifier,
			   const QCString & pretype, const QCString & array,
			   aVisibility visibility, bool staticp, bool constp,
			   bool typenamep, bool mutablep, bool volatilep,
			   const QCString & bitfield, const QCString & value,
			   QCString comment, QCString description
#ifdef ROUNDTRIP
			   , bool roundtrip, QList<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(QCString("<font face=helvetica><b>cannot add attribute <i>")
		    + name + "</i> in <i>" + QCString(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;
  QCString typeform;
  QCString stereotype;
  
  if (! pfunc) {
    typeform = (pretype.isEmpty())
      ? QCString("${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);
  }
  
  QCString 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, QCString(" ") + modifier);
        
    if (typeform != "${type}")
      decl.replace(index, 7, typeform);
    else if (typespec.type == 0) {
      QCString 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(';'), QCString(" : ") + 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) {
      QCString 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()) {
      QCString 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;
}
示例#21
0
bool UmlAttribute::new_one(Class * container, const QCString & name,
			   UmlTypeSpec typespec, aVisibility visibility,
			   bool staticp, bool finalp, bool transientp,
			   bool volatilep, const QCString & array,
			   const QCString & value, QCString comment,
			   QCString description, QCString annotation
#ifdef ROUNDTRIP
			   , bool roundtrip, QList<UmlItem> & expected_order
#endif
			   )
{
#ifdef TRACE
  cout << "ATTRIBUTE '" << name << "'\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(container, name)) == 0)) {
#endif
    at = UmlBaseAttribute::create(cl, name);
    if (at == 0) {
      JavaCatWindow::trace(QCString("<font face=helvetica><b>cannot add attribute <i>")
			   + name + "</i> in <i>" + cl->name() 
			   + "</i></b></font><br>");  
      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);
  
  QCString decl = JavaSettings::attributeDecl("");
  int index = decl.find("${type}");
  
  if ((index == -1) || (decl.find("${name}") == -1)) {
    decl = "  ${comment}${@}${visibility}${static}${final}${transient}${volatile}${type} ${name}${value};";
    index = decl.find("${type}");
  }
  
#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() != finalp) {
      at->set_isReadOnly(finalp);
      container->set_updated();
    }
    
    if (at->isJavaTransient() != transientp) {
      at->set_isJavaTransient(transientp);
      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 (!array.isEmpty())
      decl.insert(index + 7, "${multiplicity}");
    
    if (neq(at->multiplicity(), array)) {
      at->set_Multiplicity(array);
      container->set_updated();
    }
    
    QCString 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 (nequal(at->javaAnnotations(), annotation)) {
      at->set_JavaAnnotations(annotation);
      container->set_updated();
    }
    
    QCString stereotype;
    bool force_ste = FALSE;
    
    if (cl->stereotype() == "enum") {
      stereotype = "attribute";
      force_ste = TRUE;
    }
    else if (typespec.type == 0) {
      QCString 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}>");
	force_ste = TRUE;
      }
    }
    
    if (at->visibility() != visibility) {
      at->set_Visibility(visibility);
      container->set_updated();
    }
    
    if (neq(at->stereotype(), stereotype)) {
      QCString jst;
      
      if (! at->stereotype().isEmpty())
	jst = JavaSettings::relationAttributeStereotype(at->stereotype());
      
      if ((force_ste) ? (jst != stereotype) : (jst == "attribute")) {
	at->set_Stereotype(stereotype);
	container->set_updated();
      }
    }
    
    if (neq(at->javaDecl(), decl)) {
      at->set_JavaDecl(decl);
      container->set_updated();
    }
    
    if (!at->type().equal(typespec)) {
      at->set_Type(typespec);
      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 (finalp)
      at->set_isReadOnly(TRUE);
    
    if (transientp)
      at->set_isJavaTransient(TRUE);
    
    if (volatilep)
      at->set_isVolatile(TRUE);
    
    if (staticp)
      at->set_isClassMember(TRUE);
    
    if (!array.isEmpty()) {
      decl.insert(index + 7, "${multiplicity}");
      at->set_Multiplicity(array);
    }
    
    if (! value.isEmpty())
      at->set_DefaultValue(value);
    
    if (! annotation.isEmpty())
      at->set_JavaAnnotations(annotation);
    
    if ((typespec.type == 0) && (cl->stereotype() != "enum")) {
      QCString t = typespec.explicit_type;
      int index2;
      
      if (!t.isEmpty() &&
	  (t.at(t.length() - 1) == '>') &&
	  ((index2 = t.find('<')) > 0)) {
	at->set_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}>");
      }
    }
    
    at->set_Visibility(visibility);
    
    if (cl->stereotype() == "enum") {
      at->set_JavaDecl(decl);
      at->set_Stereotype("attribute");
    }
    else if (decl != JavaSettings::attributeDecl(""))
      at->set_JavaDecl(decl);
    
    at->set_Type(typespec);
    
#ifdef ROUNDTRIP
    if (roundtrip)
      expected_order.append(at);
  }
#endif
  
  return TRUE;
}
示例#22
0
Key *
BaseG::parseKeyData(const QCString &output, int &offset, Key *key /* = 0 */)
// This function parses the data for a single key which is output by GnuPG
// with the following command line arguments:
//   --batch --list-public-keys --with-fingerprint --with-colons
//   --fixed-list-mode [--no-expensive-trust-checks]
// It expects the key data to start at offset and returns the start of
// the next key's data in offset.
// Subkeys are currently ignored.
{
    int index = offset;

    if((strncmp(output.data() + offset, "pub:", 4) != 0)
            && (strncmp(output.data() + offset, "sec:", 4) != 0))
    {
        return 0;
    }

    if(key == 0)
        key = new Key();
    else
        key->clear();

    QCString keyID;
    bool firstKey = true;

    while(true)
    {
        int eol;
        // search the end of the current line
        if((eol = output.find('\n', index)) == -1)
            break;

        bool bIsPublicKey = false;
        if((bIsPublicKey = !strncmp(output.data() + index, "pub:", 4))
                || !strncmp(output.data() + index, "sec:", 4))
        {
            // line contains primary key data
            // Example: pub:f:1024:17:63CB691DFAEBD5FC:860451781::379:-:::scESC:

            // abort parsing if we found the start of the next key
            if(!firstKey)
                break;
            firstKey = false;

            key->setSecret(!bIsPublicKey);

            Subkey *subkey = new Subkey(QCString(), !bIsPublicKey);

            int pos = index + 4; // begin of 2nd field
            int pos2 = output.find(':', pos);
            for(int field = 2; field <= 12; field++)
            {
                switch(field)
                {
                    case 2: // the calculated trust
                        if(pos2 > pos)
                        {
                            switch(output[pos])
                            {
                                case 'o': // unknown (this key is new to the system)
                                    break;
                                case 'i': // the key is invalid, e.g. missing self-signature
                                    subkey->setInvalid(true);
                                    key->setInvalid(true);
                                    break;
                                case 'd': // the key has been disabled
                                    subkey->setDisabled(true);
                                    key->setDisabled(true);
                                    break;
                                case 'r': // the key has been revoked
                                    subkey->setRevoked(true);
                                    key->setRevoked(true);
                                    break;
                                case 'e': // the key has expired
                                    subkey->setExpired(true);
                                    key->setExpired(true);
                                    break;
                                case '-': // undefined (no path leads to the key)
                                case 'q': // undefined (no trusted path leads to the key)
                                case 'n': // don't trust this key at all
                                case 'm': // the key is marginally trusted
                                case 'f': // the key is fully trusted
                                case 'u': // the key is ultimately trusted (secret key available)
                                    // These values are ignored since we determine the key trust
                                    // from the trust values of the user ids.
                                    break;
                                default:
                                    kdDebug(5100) << "Unknown trust value\n";
                            }
                        }
                        break;
                    case 3: // length of key in bits
                        if(pos2 > pos)
                            subkey->setKeyLength(output.mid(pos, pos2 - pos).toUInt());
                        break;
                    case 4: //  the key algorithm
                        if(pos2 > pos)
                            subkey->setKeyAlgorithm(output.mid(pos, pos2 - pos).toUInt());
                        break;
                    case 5: // the long key id
                        keyID = output.mid(pos, pos2 - pos);
                        subkey->setKeyID(keyID);
                        break;
                    case 6: // the creation date (in seconds since 1970-01-01 00:00:00)
                        if(pos2 > pos)
                            subkey->setCreationDate(output.mid(pos, pos2 - pos).toLong());
                        break;
                    case 7: // the expiration date (in seconds since 1970-01-01 00:00:00)
                        if(pos2 > pos)
                            subkey->setExpirationDate(output.mid(pos, pos2 - pos).toLong());
                        else
                            subkey->setExpirationDate(-1);   // key expires never
                        break;
                    case 8: // local ID (ignored)
                    case 9: // Ownertrust (ignored for now)
                    case 10: // User-ID (always empty in --fixed-list-mode)
                    case 11: // signature class (always empty except for key signatures)
                        break;
                    case 12: // key capabilities
                        for(int i = pos; i < pos2; i++)
                            switch(output[i])
                            {
                                case 'e':
                                    subkey->setCanEncrypt(true);
                                    break;
                                case 's':
                                    subkey->setCanSign(true);
                                    break;
                                case 'c':
                                    subkey->setCanCertify(true);
                                    break;
                                case 'E':
                                    key->setCanEncrypt(true);
                                    break;
                                case 'S':
                                    key->setCanSign(true);
                                    break;
                                case 'C':
                                    key->setCanCertify(true);
                                    break;
                                default:
                                    kdDebug(5100) << "Unknown key capability\n";
                            }
                        break;
                }
                pos = pos2 + 1;
                pos2 = output.find(':', pos);
            }
            key->addSubkey(subkey);
        }
        else if(!strncmp(output.data() + index, "uid:", 4))
        {
            // line contains a user id
            // Example: uid:f::::::::Philip R. Zimmermann <*****@*****.**>:

            UserID *userID = new UserID("");

            int pos = index + 4; // begin of 2nd field
            int pos2 = output.find(':', pos);
            for(int field = 2; field <= 10; field++)
            {
                switch(field)
                {
                    case 2: // the calculated trust
                        if(pos2 > pos)
                        {
                            switch(output[pos])
                            {
                                case 'i': // the user id is invalid, e.g. missing self-signature
                                    userID->setInvalid(true);
                                    break;
                                case 'r': // the user id has been revoked
                                    userID->setRevoked(true);
                                    break;
                                case '-': // undefined (no path leads to the key)
                                case 'q': // undefined (no trusted path leads to the key)
                                    userID->setValidity(KPGP_VALIDITY_UNDEFINED);
                                    break;
                                case 'n': // don't trust this key at all
                                    userID->setValidity(KPGP_VALIDITY_NEVER);
                                    break;
                                case 'm': // the key is marginally trusted
                                    userID->setValidity(KPGP_VALIDITY_MARGINAL);
                                    break;
                                case 'f': // the key is fully trusted
                                    userID->setValidity(KPGP_VALIDITY_FULL);
                                    break;
                                case 'u': // the key is ultimately trusted (secret key available)
                                    userID->setValidity(KPGP_VALIDITY_ULTIMATE);
                                    break;
                                default:
                                    kdDebug(5100) << "Unknown trust value\n";
                            }
                        }
                        break;
                    case 3: // these fields are empty
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                        break;
                    case 10: // User-ID
                        QCString uid = output.mid(pos, pos2 - pos);
                        // replace "\xXX" with the corresponding character;
                        // other escaped characters, i.e. \n, \r etc., are ignored
                        // because they shouldn't appear in user IDs
                        for(int idx = 0 ; (idx = uid.find("\\x", idx)) >= 0 ; ++idx)
                        {
                            char str[2] = "x";
                            str[0] = (char) QString(uid.mid(idx + 2, 2)).toShort(0, 16);
                            uid.replace(idx, 4, str);
                        }
                        QString uidString = QString::fromUtf8(uid.data());
                        // check whether uid was utf-8 encoded
                        bool isUtf8 = true;
                        for(unsigned int i = 0; i + 1 < uidString.length(); ++i)
                        {
                            if(uidString[i].unicode() == 0xdbff &&
                                    uidString[i + 1].row() == 0xde)
                            {
                                // we found a non-Unicode character (see QString::fromUtf8())
                                isUtf8 = false;
                                break;
                            }
                        }
                        if(!isUtf8)
                        {
                            // The user id isn't utf-8 encoded. It was most likely
                            // created with PGP which either used latin1 or koi8-r.
                            kdDebug(5100) << "User Id '" << uid
                                          << "' doesn't seem to be utf-8 encoded." << endl;

                            // We determine the ratio between non-ASCII and ASCII chars.
                            // A koi8-r user id should have lots of non-ASCII chars.
                            int nonAsciiCount = 0, asciiCount = 0;

                            // We only look at the first part of the user id (i. e. everything
                            // before the email address resp. before a comment)
                            for(signed char *ch = (signed char *)uid.data();
                                    *ch && (*ch != '(') && (*ch != '<');
                                    ++ch)
                            {
                                if(((*ch >= 'A') && (*ch <= 'Z'))
                                        || ((*ch >= 'a') && (*ch <= 'z')))
                                    ++asciiCount;
                                else if(*ch < 0)
                                    ++nonAsciiCount;
                            }
                            kdDebug(5100) << "ascii-nonAscii ratio : " << asciiCount
                                          << ":" << nonAsciiCount << endl;
                            if(nonAsciiCount > asciiCount)
                            {
                                // assume koi8-r encoding
                                kdDebug(5100) << "Assume koi8-r encoding." << endl;
                                QTextCodec *codec = QTextCodec::codecForName("KOI8-R");
                                uidString = codec->toUnicode(uid.data());
                                // check the case of the first two characters to find out
                                // whether the user id is probably CP1251 encoded (for some
                                // reason in CP1251 the lower case characters have smaller
                                // codes than the upper case characters, so if the first char
                                // of the koi8-r decoded user id is lower case and the second
                                // char is upper case then it's likely that the user id is
                                // CP1251 encoded)
                                if((uidString.length() >= 2)
                                        && (uidString[0].lower() == uidString[0])
                                        && (uidString[1].upper() == uidString[1]))
                                {
                                    // koi8-r decoded user id has inverted case, so assume
                                    // CP1251 encoding
                                    kdDebug(5100) << "No, it doesn't seem to be koi8-r. "
                                                  "Use CP 1251 instead." << endl;
                                    QTextCodec *codec = QTextCodec::codecForName("CP1251");
                                    uidString = codec->toUnicode(uid.data());
                                }
                            }
                            else
                            {
                                // assume latin1 encoding
                                kdDebug(5100) << "Assume latin1 encoding." << endl;
                                uidString = QString::fromLatin1(uid.data());
                            }
                        }
                        userID->setText(uidString);
                        break;
                }
                pos = pos2 + 1;
                pos2 = output.find(':', pos);
            }

            // user IDs are printed in UTF-8 by gpg (if one uses --with-colons)
            key->addUserID(userID);
        }
        else if(!strncmp(output.data() + index, "fpr:", 4))
        {
            // line contains a fingerprint
            // Example: fpr:::::::::17AFBAAF21064E513F037E6E63CB691DFAEBD5FC:

            if(key == 0)  // invalid key data
                break;

            // search the fingerprint (it's in the 10th field)
            int pos = index + 4;
            for(int i = 0; i < 8; i++)
                pos = output.find(':', pos) + 1;
            int pos2 = output.find(':', pos);

            key->setFingerprint(keyID, output.mid(pos, pos2 - pos));
        }
        index = eol + 1;
    }

    //kdDebug(5100) << "finished parsing key data\n";

    offset = index;

    return key;
}