pike.git / lib / modules / Tools.pmod / AutoDoc.pmod / ProcessXML.pmod

version» Context lines:

pike.git/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod:110:   // <ref/>   // <section/>   // <string/>   // <ul/>   // </text>      //========================================================================   // From source file to XML   //========================================================================    - // Wrap child in the proper modules and namespace. - protected object makeWrapper(array(string) modules, object|void child) - { -  object m; -  if (child->objtype != "autodoc") { -  if (child->objtype != "namespace") { -  string namespace = "predef"; // Default namespace. -  if (sizeof(modules) && has_suffix(modules[0], "::")) { -  // The parent module list starts with a namespace. -  namespace = modules[0][..<2]; -  modules = modules[1..]; -  } -  foreach(reverse(modules), string n) { -  m = .PikeObjects.Module(); -  m->name = n; -  if (child) -  m->AddChild(child); -  child = m; -  } -  m = .PikeObjects.NameSpace(); -  m->name = namespace; -  m->AddChild(child); -  child = m; -  } -  m = .PikeObjects.AutoDoc(); -  m->AddChild(child); -  child = m; -  } -  return child; - } -  +    //! This function extracts documentation from a file. The parameters   //! @[type], @[name], and @[parentModules] are used only when   //! @[pikeMode] != 0 and no C-style doc comments are present.   //!   //! @param filename   //! The file to extract from.   //! @param pikeMode   //! Non-zero if it is a Pike file. If the file contains   //! style doc comments, C-mode is used despite pikeMode != 0.   //! @param type
pike.git/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod:169:   //!   //! @example   //! // To extract doc for Foo.Bar.Ippa:   //! string xml = extractXML("lib/modules/Foo.pmod/Bar.pmod/Ippa.pike", 1,   //! "class", "Ippa", ({ "Foo", "Bar" }));   //!   string extractXML(string filename, int|void pikeMode, string|void type,    string|void name, array(string)|void parentModules,    void|.Flags flags)   { -  if (zero_type(flags)) flags = .FLAG_NORMAL; +  if (undefinedp(flags)) flags = .FLAG_NORMAL;       // extract the file...    // check if there are C style doc comments in it,    // because if there are, the CExtractor should be    // used instead of the PikeExtractor    int styleC = !pikeMode;    int stylePike = pikeMode;       string contents = Stdio.File(filename)->read();   
pike.git/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod:197:    // stylePike = 1;    // if (stylePike && styleC)    // processError("both C and Pike style doc comments in file " + filename);    // }       if (styleC && has_value(contents, "/*!")) {    string namespace = ((parentModules||({})) + ({"predef::"}))[0];    if (has_suffix(namespace, "::")) {    namespace = namespace[..<2];    } +  // FIXME: Ought to handle emacs-style encoding directives. +  catch { contents = utf8_to_string(contents); };    object m = .CExtractor.extract(contents, filename, namespace, flags);    return m->xml(flags);    }    else if(stylePike && has_value(contents, "//!")) { -  +  // FIXME: Ought to handle #charset. +  catch { contents = utf8_to_string(contents); };    if(has_suffix(filename, ".pmod.in")) {    contents = replace(contents, "@module@",    "\"___" + (parentModules[1..] + ({ name }))*"." +"\"");    } -  object m; +  +  // Generate empty nodes for the parentModules. +  object root = .PikeObjects.AutoDoc(); +  object m = root; +  if (type != "namespace") { +  object child = .PikeObjects.NameSpace(); +  m->addChild(child); +  m = child; +  m->name = "predef"; +  foreach(parentModules||({}); int i; string n) { +  if (!i && has_suffix(n, "::")) { +  // The parent module list starts with a namespace. +  m->name = n[..<2]; +  continue; +  } +  child = .PikeObjects.Module(); +  child->name = n; +  m->addChild(child); +  m = child; +  } +  } +     switch(type) {    case "module": -  m = .PikeExtractor.extractModule(contents, filename, name, flags); +  .PikeExtractor.extractModule(root, m, contents, filename, name, flags);    break;    default:    case "class": -  m = .PikeExtractor.extractClass(contents, filename, name, flags); +  .PikeExtractor.extractClass(root, m, contents, filename, name, flags);    break;    case "namespace": -  m = .PikeExtractor.extractNamespace(contents, filename, name, flags); +  .PikeExtractor.extractNamespace(root, contents, filename, name, flags);    break;    } -  if (m) -  return makeWrapper(parentModules, m)->xml(flags); +  +  object child, prev, next; +  for (child = root; prev != m; prev = child, child = next) { +  if (child->documentation || sizeof(child->docGroups) || +  (sizeof(child->children) > 1)) { +  return root->xml(flags);    } -  +  if (!sizeof(child->children)) break; +  next = child->children[0]; +  } +  +  // child here is either an undocumented, empty m, +  // or the (only) child to m. +  if (child->documentation || sizeof(child->docGroups) || +  sizeof(child->children)) { +  return root->xml(flags); +  } +  }    return "";   }      //========================================================================   // IMAGES MOVED TO CANONICAL FILES   //========================================================================      #define CONCAT_CHAR "."      //! Copy all images to canonical files in a flat directory.
pike.git/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod:434:    }    return type_node->render_xml();   }      protected SimpleNode mergeDoc(SimpleNode orig, SimpleNode new)   {    // NB: There can only be one <text> node in a <doc> node,    // and it comes first among the element nodes.    SimpleNode orig_text = orig->get_first_element("text");    SimpleNode new_text = new->get_first_element("text"); -  if (new_text && sizeof(String.trim_all_whites(new_text->value_of_node()))) { +  if (new_text && sizeof(String.trim(new_text->value_of_node()))) {    if (!orig_text) {    orig->add_child(new_text); -  } else if (!sizeof(String.trim_all_whites(orig_text->value_of_node()))) { +  } else if (!sizeof(String.trim(orig_text->value_of_node()))) {    orig->replace_child(orig_text, new_text);    } else {    orig_text->replace_children(orig_text->get_children() +    new_text->get_children());    }    }       // Append the remaining (typically <group>) nodes in new after    // the previously existing in orig.    array(SimpleNode) new_children = new->get_children() - ({ new_text });
pike.git/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod:509:    dest_attrs[attr] = val;    }    }       foreach(dest->get_children(), SimpleNode node) {    string name = getName(node);    if (name) {    dest_children[name] = node;    } else if (isDoc(node)) {    // Strip empty doc nodes. -  if (sizeof(String.trim_all_whites(node->value_of_node()))) +  if (sizeof(String.trim(node->value_of_node())))    dest_has_doc = node;    } else if (isDocGroup(node)) {    // Docgroups are special:    // * More than one symbol my be documented in the group.    // * The same symbol may be documented multiple times    // with different signatures.    foreach(node->get_elements(), SimpleNode sub) {    if (name = getName(sub)) {    dest_groups[name] += ({ node });    }    }    } else if (isModifiers(node)) {    dest_modifiers = (multiset(string))node->get_elements()->get_any_name();    } else if (!isText(node) || -  sizeof(String.trim_all_whites(node->value_of_node()))) { +  sizeof(String.trim(node->value_of_node()))) {    other_children += ({ node });    }    }       array(SimpleNode) children = source->get_elements();    foreach(children; int i; SimpleNode node) {    switch(node->get_any_name()) {    case "appendix":    // FIXME: Warn when not in compat mode.    // FALL_THROUGH
pike.git/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod:583:    break;       case "docgroup":    {    foreach(node->get_elements(), SimpleNode sub) {    string name = getName(sub);    if (!name) continue;    dest_groups[name] += ({ node });    }    SimpleNode doc = node->get_first_element("doc"); -  if (doc && !sizeof(String.trim_all_whites(doc->value_of_node()))) { +  if (doc && !sizeof(String.trim(doc->value_of_node()))) {    // The doc is NULL.    node->remove_child(doc);    }    }    children[i] = 0;    break;       case "modifiers":    dest_modifiers |= (multiset)node->get_elements()->get_any_name();    break;       case "doc": -  if (!sizeof(String.trim_all_whites(node->value_of_node()))) { +  if (!sizeof(String.trim(node->value_of_node()))) {    // NULL doc.    } else if (dest_has_doc) {    if ((node->get_attributes()["placeholder"] == "true") || -  (String.trim_all_whites(node->value_of_node()) == -  String.trim_all_whites(dest_has_doc->value_of_node()))) { +  (String.trim(node->value_of_node()) == +  String.trim(dest_has_doc->value_of_node()))) {    // New doc is placeholder or same as old.    } else if (dest_has_doc->get_attributes()["placeholder"] != "true") {    // werror("Original doc: %O\n", dest_has_doc->value_of_node());    // werror("New doc: %O\n", node->value_of_node());    if (isNameSpace(dest))    processWarning("Duplicate documentation for namespace " +    getName(dest));    else if (isClass(dest))    processWarning("Duplicate documentation for class " +    getName(dest));
pike.git/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod:631:    dest_has_doc = node;    }    } else {    dest_has_doc = node;    }    children[i] = 0;    break;       default:    if (!isText(node) || -  sizeof(String.trim_all_whites(node->value_of_node()))) { +  sizeof(String.trim(node->value_of_node()))) {    if (node->get_any_name() != "source-position") {    werror("Got other node: %O\n", node->render_xml());    }    other_children += ({ node });    }    children[i] = 0;    break;    }    }   
pike.git/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod:792:    recurseAppears(namespace, child, current);   }      //! Take care of all the @@appears and @@belongs directives everywhere,   //! and rearranges the nodes in the tree accordingly   //!   //! @param root   //! The root (@tt{<autodoc>@}) node of the documentation tree.   void handleAppears(SimpleNode root, .Flags|void flags)   { -  if (zero_type(flags)) flags = .FLAG_NORMAL; +  if (undefinedp(flags)) flags = .FLAG_NORMAL;    tasks = ({ });    foreach(root->get_elements("namespace"), SimpleNode namespaceNode) {    string namespace = namespaceNode->get_attributes()->name + "::";    foreach(namespaceNode->get_children(), SimpleNode child) {    if ((<"module", "class", "docgroup">)[child->get_any_name()]) {    recurseAppears(namespace, child, namespaceNode);    }    }    }    tasks = Array.sort_array(
pike.git/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod:962:    mapping(string:multiset(string)) namespace_extends = ([]);    string namespace = "predef";       array(array(string|array(Scope))) namespaceStack = ({});       void enter(string|void type, string|void name) {    //werror("entering scope type(%O), name(%O)\n", type, name);    if (type == "namespace") {    namespaceStack += ({ ({ namespace, scopes[name] }) });    scopes[namespace = name] = ({ Scope(type, name+"::") }); -  if (name = ([ "7.8":"7.7", +  if (name = ([ +  "predef":"8.1", +  "8.0":"7.9", +  "7.8":"7.7",    "7.6":"7.5",    "7.4":"7.3",    "7.2":"7.1", -  "7.0":"0.7" ])[name]) { +  "7.0":"0.7", +  ])[name]) {    // Add an alias for development version.    scopes[name] = scopes[namespace];    }    } else {    if (!sizeof(scopes[namespace]||({}))) {    werror("WARNING: Implicit enter of namespace %s:: for %s %s\n",    namespace, type, name||"");    scopes[namespace] = ({ Scope("namespace", namespace+"::") });    }    scopes[namespace] += ({ Scope(type, name) });
pike.git/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod:1285:    name += "::";    path = name;    } else if (type != "autodoc") {    error("Unsupported node type: %O, name: %O, path: %O\n",    type, name, path);    }    if (!(<"autodoc", "namespace", "module", "class", "method", "enum">)[type]) {    error("Unsupported node type: %O, name: %O, path: %O\n",    type, name, path);    } -  this_program::path = path; +  this::path = path;    enterNode(tree);    }       //! This function improves the symbol resolution by adding    //! implicit inherits for modules in compatibility namespaces.    void addImplicitInherits(string|void fallback_namespace)    {    switch(type) {    default:    return;
pike.git/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod:1493:       protected void warn(sprintf_format fmt, sprintf_args ... args)    {    if (flags & .FLAG_VERB_MASK) {    werror(fmt, @args);    }    }       protected void create(NScope scopes, string|void logfile, .Flags|void flags)    { -  this_program::scopes = scopes; -  this_program::logfile = logfile; -  if (zero_type(flags)) flags = .FLAG_NORMAL; -  this_program::flags = flags; +  this::scopes = scopes; +  this::logfile = logfile; +  if (undefinedp(flags)) flags = .FLAG_NORMAL; +  this::flags = flags;    }    -  protected void destroy() +  protected void _destruct()    {    if (sizeof(failures)) {    logfile = logfile || "resolution.log";    warn("Resolution failed for %d symbols. Logging to %s\n",    sizeof(failures), logfile);    Stdio.File f = Stdio.File(logfile, "cwt");    f->write("Reference target: Reference source:references\n\n");    mapping(string:array(string)) rev = ([]);    foreach(sort(indices(failures)), string ref) {    mapping(string:int) where = failures[ref];
pike.git/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod:1599:    {    if (!sizeof(ref)) {    return top->name;    }    int pos = sizeof(stack);    NScope current = top;    if (has_suffix(ref[0], "::")) {    // Inherit or namespace.    switch(ref[0]) {    case "this_program::": +  case "this::":    while (pos) {    if ((<"class", "module", "namespace">)[current->type]) {    return current->lookup(ref[1..]);    }    pos--;    current = stack[pos];    }    return 0;    case "::": -  +  if ((sizeof(ref) > 1) && (ref[1] == "this_program")) { +  // Handle ::this_program. +  NScope this_p; +  while (pos--) { +  if ((current->type == "class") || (current->type == "module")) { +  this_p = current; +  current = stack[pos]; +  break; +  } +  current = stack[pos]; +  } +  if (this_p) { +  ref[1] = splitRef(this_p->name)[-1]; +  } else { +  current = top; +  pos = sizeof(stack); +  } +  }    while(pos) {    if (current->inherits) {    foreach(current->inherits; ; string|NScope scope) {    if (stringp(scope)) scope = lookup(scope);    if (objectp(scope)) {    string res = scope->lookup(ref[1..]);    if (res) return res;    }    }    }
pike.git/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod:1633:    // Strip the trailing "::".    string inh = ref[0][..sizeof(ref[0])-3];    // Map intermediate version namespaces to existing.    // FIXME: This ought be done based on the set of namespaces.    inh = ([    "0.7":"7.0",    "7.1":"7.2",    "7.3":"7.4",    "7.5":"7.6",    "7.7":"7.8", -  "7.9":"predef", +  "7.9":"8.0", +  "8.1":"predef",    ])[inh] || inh;    while(pos) {    string|NScope scope;    if (current->inherits && (scope = current->inherits[inh])) {    if (stringp(scope)) scope = lookup(scope);    if (objectp(scope)) {    string res = scope->lookup(ref[1..]);    if (res) return res;    }    }