"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/tags.c" between
tin-2.4.4.tar.xz and tin-2.4.5.tar.xz

About: TIN is a threaded NNTP and spool based UseNet newsreader.

tags.c  (tin-2.4.4.tar.xz):tags.c  (tin-2.4.5.tar.xz)
/* /*
* Project : tin - a Usenet reader * Project : tin - a Usenet reader
* Module : tags.c * Module : tags.c
* Author : Jason Faultless <jason@altarstone.com> * Author : Jason Faultless <jason@altarstone.com>
* Created : 1999-12-06 * Created : 1999-12-06
* Updated : 2010-04-02 * Updated : 2020-08-04
* Notes : Split out from other modules * Notes : Split out from other modules
* *
* Copyright (c) 1999-2020 Jason Faultless <jason@altarstone.com> * Copyright (c) 1999-2021 Jason Faultless <jason@altarstone.com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
skipping to change at line 45 skipping to change at line 45
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef TIN_H #ifndef TIN_H
# include "tin.h" # include "tin.h"
#endif /* !TIN_H */ #endif /* !TIN_H */
/* Local prototypes */ /* Local prototypes */
static int get_multipart_info(int base_index, MultiPartInfo *setme);
static int get_multiparts(int base_index, MultiPartInfo **malloc_and_setme_info)
;
static int look_for_multipart_info(int base_index, MultiPartInfo *setme, char st
art, char stop, int *offset);
static t_bool parse_range(char *range, int min, int max, int curr, int *range_st art, int *range_end); static t_bool parse_range(char *range, int min, int max, int curr, int *range_st art, int *range_end);
int num_of_tagged_arts = 0; int num_of_tagged_arts = 0;
/* /*
* Parses a subject header of the type "multipart message subject (01/42)"
* into a MultiPartInfo struct, or fails if the message subject isn't in the
* right form.
*
* @return nonzero on success
*/
static int
get_multipart_info(
int base_index,
MultiPartInfo *setme)
{
int i, j, offi, offj;
MultiPartInfo setmei, setmej;
i = look_for_multipart_info(base_index, &setmei, '[', ']', &offi);
j = look_for_multipart_info(base_index, &setmej, '(', ')', &offj);
/* Ok i hits first */
if (offi > offj) {
*setme = setmei;
return i;
}
/* Its j or they are both the same (which must be zero!) so we don't care
*/
*setme = setmej;
return j;
}
static int
look_for_multipart_info(
int base_index,
MultiPartInfo* setme,
char start,
char stop,
int *offset)
{
MultiPartInfo tmp;
char *subj;
char *pch;
*offset = 0;
/* entry assertions */
assert(0 <= base_index && base_index < grpmenu.max && "invalid base_index
");
assert(setme != NULL && "setme must not be NULL");
/* parse the message */
subj = arts[base[base_index]].subject;
if (!(pch = strrchr(subj, start)))
return 0;
if (!isdigit((int) pch[1]))
return 0;
tmp.base_index = base_index;
tmp.subject_compare_len = pch - subj;
tmp.part_number = (int) strtol(pch + 1, &pch, 10);
if (*pch != '/' && *pch != '|')
return 0;
if (!isdigit((int) pch[1]))
return 0;
tmp.total = (int) strtol(pch + 1, &pch, 10);
if (*pch != stop)
return 0;
tmp.subject = subj;
*setme = tmp;
*offset = pch - subj;
return 1;
}
/*
* Tries to find all the parts to the multipart message pointed to by
* base_index.
*
* Weakness(?): only walks through the base messages.
*
* @return on success, the number of parts found. On failure, zero if not a
* multipart or the negative value of the first missing part.
* @param base_index index pointing to one of the messages in a multipart
* message.
* @param malloc_and_setme_info on success, set to a malloced array the
* parts found. Untouched on failure.
*/
static int
get_multiparts(
int base_index,
MultiPartInfo **malloc_and_setme_info)
{
MultiPartInfo tmp, tmp2;
MultiPartInfo *info = NULL;
int i;
int part_index;
/* entry assertions */
assert(0 <= base_index && base_index < grpmenu.max && "Invalid base index
");
assert(malloc_and_setme_info != NULL && "malloc_and_setme_info must not b
e NULL");
/* make sure this is a multipart message... */
if (!get_multipart_info(base_index, &tmp) || tmp.total < 1)
return 0;
/* make a temporary buffer to hold the multipart info... */
info = my_malloc(sizeof(MultiPartInfo) * tmp.total);
/* zero out part-number for the repost check below */
for (i = 0; i < tmp.total; ++i)
info[i].part_number = -1;
/* try to find all the multiparts... */
for (i = 0; i < grpmenu.max; ++i) {
if (strncmp(arts[base[i]].subject, tmp.subject, tmp.subject_compa
re_len))
continue;
if (!get_multipart_info(i, &tmp2))
continue;
part_index = tmp2.part_number - 1;
/* skip the "blah (00/102)" info messages... */
if (part_index < 0)
continue;
/* skip insane "blah (103/102) subjects... */
if (part_index >= tmp.total)
continue;
/* repost check: do we already have this part? */
if (info[part_index].part_number != -1) {
assert(info[part_index].part_number == tmp2.part_number &
& "bookkeeping error");
continue;
}
/* we have a match, hooray! */
info[part_index] = tmp2;
}
/* see if we got them all. */
for (i = 0; i < tmp.total; ++i) {
if (info[i].part_number != i + 1) {
free(info);
return -(i + 1); /* missing part #(i+1) */
}
}
/* looks like a success .. */
*malloc_and_setme_info = info;
return tmp.total;
}
/*
* Tags all parts of a multipart index if base_index points * Tags all parts of a multipart index if base_index points
* to a multipart message and all its parts can be found. * to a multipart message and all its parts can be found.
* *
* @param base_index points to one message in a multipart message. * @param base_index points to one message in a multipart message.
* @return number of messages tagged, or zero on failure * @return number of messages tagged, or zero on failure
*/ */
int int
tag_multipart( tag_multipart(
int base_index) int arts_index)
{ {
MultiPartInfo *info = NULL; MultiPartInfo *info = NULL;
int i; int i;
const int qty = get_multiparts(base_index, &info); int qty;
t_bool untagging = FALSE;
for_each_art(i) {
if (!global_look_for_multipart(i, '[', ']'))
global_look_for_multipart(i, '(', ')');
}
qty = global_get_multiparts(arts_index, &info, TRUE);
/* check for failure... */ /* check for failure... */
if (qty == 0) { if (qty == 0) {
info_message(_(txt_info_not_multipart_message)); info_message(_(txt_info_not_multipart_message));
return 0; return 0;
} }
if (qty < 0) { if (qty < 0) {
info_message(_(txt_info_missing_part), -qty); info_message(_(txt_info_missing_part), -qty);
return 0; return 0;
} }
/* /*
* if any are already tagged, untag 'em first * if any are already tagged, untag 'em
* so num_of_tagged_arts doesn't get corrupted
*/ */
for (i = 0; i < qty; ++i) { for (i = 0; i < qty; ++i) {
if (arts[base[info[i].base_index]].tagged != 0) if (arts[info[i].arts_index].tagged != 0) {
untag_article(base[info[i].base_index]); untagging = TRUE;
while (i < qty)
untag_article(info[i++].arts_index);
}
} }
/* /*
* get_multiparts() sorts info by part number, * get_multiparts() sorts info by part number,
* so a simple for loop tags in the right order * so a simple for loop tags in the right order
*
* only tag if we are not untagging
*/ */
for (i = 0; i < qty; ++i) if (!untagging) {
arts[base[info[i].base_index]].tagged = ++num_of_tagged_arts; for (i = 0; i < qty; ++i)
arts[info[i].arts_index].tagged = ++num_of_tagged_arts;
}
free(info); free(info);
return qty; return qty;
} }
/* /*
* Return the highest tag number of any article in thread * Return the highest tag number of any article in thread
* rooted at base[n] * rooted at base[n]
*/ */
skipping to change at line 355 skipping to change at line 219
set_range( set_range(
int level, int level,
int min, int min,
int max, int max,
int curr) int curr)
{ {
char *range; char *range;
char *prompt; char *prompt;
int artnum; int artnum;
int i; int i;
int depth;
int range_min; int range_min;
int range_max; int range_max;
switch (level) { switch (level) {
case SELECT_LEVEL: case SELECT_LEVEL:
range = tinrc.default_range_select; range = tinrc.default_range_select;
break; break;
case GROUP_LEVEL: case GROUP_LEVEL:
range = tinrc.default_range_group; range = tinrc.default_range_group;
skipping to change at line 426 skipping to change at line 289
case THREAD_LEVEL: case THREAD_LEVEL:
/* /*
* Debatably should clear all of arts[] depending on how you * Debatably should clear all of arts[] depending on how you
* interpret the (non)spec * interpret the (non)spec
*/ */
for (i = 0; i < grpmenu.max; i++) { / * Clear existing range */ for (i = 0; i < grpmenu.max; i++) { / * Clear existing range */
for_each_art_in_thread(artnum, i) for_each_art_in_thread(artnum, i)
arts[artnum].inrange = FALSE; arts[artnum].inrange = FALSE;
} }
depth = 1; i = 1;
for_each_art_in_thread(artnum, thread_basenote) { for_each_art_in_thread(artnum, thread_basenote) {
if (depth > range_max) if (i > range_max)
break; break;
if (depth >= range_min) if (i >= range_min)
arts[artnum].inrange = TRUE; arts[artnum].inrange = TRUE;
depth++; i++;
} }
break; break;
default: default:
return FALSE; return FALSE;
/* NOTREACHED */ /* NOTREACHED */
break; break;
} }
return TRUE; return TRUE;
} }
 End of changes. 15 change blocks. 
173 lines changed or deleted 28 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)