pike.git / lib / modules / Parser.pmod / RCS.pike

version» Context lines:

pike.git/lib/modules/Parser.pmod/RCS.pike:59:   //! Data for all revisions of the file. The indices of the mapping are   //! the revision numbers, whereas the values are the data from the   //! corresponding revision.   mapping(string:Revision) revisions;      //! Data for all revisions on the trunk, sorted in the same order as the   //! RCS file stored them - ie descending, most recent first, I'd assume   //! (rcsfile(5), of course, fails to state such irrelevant information).   array(Revision) trunk = ({});    + //! Feature detection constant for the @tt{max_revisions@} argument + //! to @[create()], @[parse()] and @[parse_delta_sections()]. + constant max_revisions_supported = 1; +    protected mapping parse_mapping(array data)   {    return (mapping)(data/2);   }      protected string parse_string(string data, string|void leader)   {    return replace( data, "@@", "@" );   }   
pike.git/lib/modules/Parser.pmod/RCS.pike:86:   //! @param file_name   //! The path to the raw RCS file (includes trailing ",v"). Used   //! mainly for error reporting (truncated RCS file or similar).   //! Stored in @[rcs_file_name].   //! @param file_contents   //! If a string is provided, that string will be parsed to   //! initialize the RCS object. If a zero (@expr{0@}) is sent, no   //! initialization will be performed at all. If no value is given at   //! all, but @[file_name] was provided, that file will be loaded and   //! parsed for object initialization. - void create(string|void file_name, string|int(0..0)|void file_contents) + //! @param max_revisions + //! Maximum number of revisions to process. If unset, all revisions + //! will be processed. + void create(string|void file_name, string|int(0..0)|void file_contents, +  void|int max_revisions)   {    if(!file_name)    {    if(!file_contents)    return;    }    else    {    rcs_file_name = file_name; -  if(!zero_type(file_contents) && !file_contents) +  if(!undefinedp(file_contents) && !file_contents)    return;    if(!file_contents)    file_contents = Stdio.read_file(file_name);    if(!file_contents)    error("Couldn't read %s\n", file_name);    } -  parse(tokenize(file_contents)); +  parse(tokenize(file_contents), 0, max_revisions);   }      //! Lower-level API function for parsing only the admin section (the   //! initial chunk of an RCS file, see manpage rcsfile(5)) of an RCS   //! file. After running @[parse_admin_section], the RCS object will be   //! initialized with the values for @[head], @[branch], @[access],   //! @[branches], @[tokenize], @[tags], @[locks], @[strict_locks],   //! @[comment] and @[expand].   //! @param raw   //! The tokenized RCS file, or the raw RCS-file data.
pike.git/lib/modules/Parser.pmod/RCS.pike:189:   //! file. After running @[parse_delta_sections], the RCS object will   //! be initialized with the value of @[description] and populated   //! @[revisions] mapping and @[trunk] array. Their @[Revision] members   //! are however only populated with the members @[Revision->revision],   //! @[Revision->branch], @[Revision->time], @[Revision->author],   //! @[Revision->state], @[Revision->branches], @[Revision->rcs_next],   //! @[Revision->ancestor] and @[Revision->next].   //! @param raw   //! The tokenized RCS file, with admin section removed. (See   //! @[parse_admin_section].) + //! @param max_revisions + //! Maximum number of revisions to process. If unset, all revisions + //! will be processed.   //! @returns   //! The rest of the RCS file, delta sections removed.   //! @seealso   //! @[parse_admin_section], @[tokenize], @[parse_deltatext_sections],   //! @[parse], @[create]   //! @fixme   //! Does not handle rcsfile(5) newphrase skipping. - array parse_delta_sections(array raw) + array parse_delta_sections(array raw, void|int max_revisions)   {    string revision, ptr;    revisions = ([]);       int i;    Revision R;   loop:    for( i = 0; i<sizeof(raw); i++ )    {    switch( raw[i][0] )
pike.git/lib/modules/Parser.pmod/RCS.pike:230:    if( sizeof( raw[i] ) > 1 )    R->rcs_next = raw[i][1];    break;    case "desc":    // finito    break loop;       default:    if( sizeof(raw[i])>2 && raw[i][1] == "date" )    { +  if (max_revisions && sizeof (revisions) >= max_revisions) +  break loop; +     R = Revision();    R->revision = revision = raw[i][0];    if( String.count( revision, "." ) == 1)    trunk += ({ R });    else    {    sscanf(reverse(revision), "%*d.%s", string branch);    R->branch = branches[reverse(branch)];    }    string date = raw[i][2];
pike.git/lib/modules/Parser.pmod/RCS.pike:254:    }    break;    }    }       // finally, set all next/ancestor pointers:    foreach(values(revisions), Revision R)    {    if(ptr = R->rcs_next)    { -  Revision N = revisions[ptr]; +  if (Revision N = revisions[ptr]) {    N->rcs_prev = R->revision; // The reverse of rcs_next.       if(String.count(R->revision, ".") > 1)    {    R->next = ptr; // on a branch, the next pointer means the successor    N->ancestor = R->revision;    }    else // current revision is on the trunk:    {    R->ancestor = ptr; // on the trunk, the next pointer is the ancestor    N->next = R->revision;    }    } -  +  }    foreach(R->branches, string branch_point) { -  +  if (revisions[branch_point]) {    revisions[branch_point]->rcs_prev = R->revision;    revisions[branch_point]->ancestor = R->revision;    }    } -  +  }      #ifdef PARSER_RCS_DEBUG    // Verify that rcs_prev behaves correctly.    foreach(values(revisions), Revision R) {    string expected = (String.count(R->revision, ".") == 1 ?    R->next : R->ancestor);    if (expected != R->rcs_prev) {    error("Invalid rcs_prev calculation: Got %O, Expected %O\n"    "Revision: %O, Next: %O, Ancestor: %O, rcs_next: %O\n",    R->rcs_prev, expected, R->revision, R->next, R->ancestor,    R->rcs_next);    }    }   #endif    -  return raw[i][2..]; +  return raw[-1][2..];   }      //! @decl array(array(string)) tokenize( string data )   //! Tokenize an RCS file into tokens suitable as argument to the various   //! parse functions   //! @param data   //! The RCS file data   //! @returns   //! An array with arrays of tokens   
pike.git/lib/modules/Parser.pmod/RCS.pike:359:    //! the @tt{rcsfile(5)@} manpage outlines the sections of an RCS file    protected void create(array deltatext_section,    void|function(string, mixed ...:void) progress_callback,    void|array(mixed) progress_callback_args)    {    raw = deltatext_section;    callback = progress_callback;    callback_args = progress_callback_args;    }    -  protected string _sprintf(int|void type, mapping|void options) +  protected string _sprintf(int type)    {    string name = "DeltatextIterator";    if(type == 't')    return name;    return sprintf("%s(/* processed %d/%d revisions%s */)", name, this_no,    revisions && sizeof(revisions), (this_no ? ", now at "+this_rev : ""));    }       // @note    // this method requires that @[raw] starts with a valid deltatext entry
pike.git/lib/modules/Parser.pmod/RCS.pike:443:    //! @fixme    //! if the rcs file is truncated, this method writes a descriptive    //! error to stderr and then returns 0 - some nicer error handling    //! wouldn't hurt    protected int parse_deltatext_section(array raw, int o)    {    if( sizeof(raw)<=o || !symbol_is_revision( raw[o] ) )    return 0;       this_rev = raw[o]; +  Revision current = revisions[this_rev]; +  if (!current) return 0;       if(callback)    if(callback_args)    callback(this_rev, @callback_args);    else    callback(this_rev);    -  Revision current = revisions[this_rev]; -  +     if( raw[o+1] != "log" ) return 0;       if( sizeof(raw)<o+3 )    {    werror("Truncated CVS-file!\n");    return 0;    }       current->log = parse_string(raw[o+2]);    if( sizeof(raw) > 4 && raw[o+3] == "text" )
pike.git/lib/modules/Parser.pmod/RCS.pike:519:    return o+3;    }   }      //! Parse the RCS file @[raw] and initialize all members of this object   //! fully initialized.   //! @param raw   //! The unprocessed RCS file.   //! @param progress_callback   //! Passed on to @[parse_deltatext_sections]. + //! @param max_revisions + //! Maximum number of revisions to process. If unset, all revisions + //! will be processed.   //! @returns   //! The fully initialized object (only returned for API convenience;   //! the object itself is destructively modified to match the data   //! extracted from @[raw])   //! @seealso   //! @[parse_admin_section], @[parse_delta_sections],   //! @[parse_deltatext_sections], @[create] - this_program parse(array raw, void|function(string:void) progress_callback) + this_program parse(array raw, void|function(string:void) progress_callback, +  void|int max_revisions)   { -  parse_deltatext_sections(parse_delta_sections(parse_admin_section(raw)), +  parse_deltatext_sections(parse_delta_sections(parse_admin_section(raw), +  max_revisions),    progress_callback);    return this;   }         // Methods applying to Parser.RCS()->Revision moved out of that class so there   // will be no cyclic references (to RCS->revisions) that forces the user to do   // manual calls to gc(). / jhs, 2004-02-24      //! Returns the file contents from the revision @[rev], without performing
pike.git/lib/modules/Parser.pmod/RCS.pike:847:    //! @[get_contents_for_revision()] hasn't been called for this revision    //! yet.    //!    //! Typically you don't access this field directly, but use    //! @[get_contents_for_revision()] to retrieve it.    //!    //! @seealso    //! @[get_contents_for_revision()], @[rcs_text]    string text;    -  protected string _sprintf(int|void type) +  protected string _sprintf(int type)    {    if(type == 't')    return "Revision";    return sprintf("Revision(/* %s */)", revision||"uninitizlized");    }   }