home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume28 / yapp / part02 / range.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-29  |  12.5 KB  |  338 lines

  1. /* RANGE.C */
  2. static    char sccsid[] = "@(#)range.c 1.21 93/06/09 Copyright (c)1993 thalerd";
  3. #include <string.h>
  4. #include <time.h>
  5. #include <limits.h>
  6. #include "config.h"
  7. #include "struct.h"
  8. #include "item.h"
  9. #include "range.h"
  10. #include "globals.h"
  11. #include "dates.h"
  12. #include "macro.h"
  13. #include "lib.h"
  14. #include "sum.h"
  15. #include "stats.h"
  16. #include "xalloc.h"   /* for xfree */
  17.  
  18. /*****************************************************************************/
  19. /* TEST WHETHER ITEM IS COVERED BY THE SPECIFIED SUBSET PARAMETERS           */
  20. /*****************************************************************************/
  21. char                     /* RETURNS: 1 if in subset, 0 else */
  22. cover(i,idx,spec,act,sum,part,st) /* ARGUMENTS: */
  23. short        i;          /*    Item number                  */
  24. short        idx;
  25. short        spec;       /*    Specifiers                   */
  26. short        act;        /*    Action flag                  */
  27. sumentry_t  *sum;        /*    Item summary                 */
  28. partentry_t *part;       /*    User participation info      */
  29. status_t    *st;
  30. {
  31.    sumentry_t *s;
  32.    partentry_t *p;
  33.  
  34.    /* if (spec & OF_NONE) return 0; */
  35.    if (act==A_SKIP) return 0;
  36.    refresh_sum(i,idx,sum,part,st); /* added for sno */
  37.    s = &(sum[i-1]);
  38.    p = &(part[i-1]);
  39.    if (!s->flags) return 0;
  40.    if (st->string[0] && !strstr(get_subj(idx,i-1,sum),st->string)) 
  41.         return 0;
  42.    if (st->author[0] &&  strcmp(get_auth(idx,i-1,sum),st->author)) 
  43.         return 0;
  44.    if (st->since  > s->last) return 0; 
  45.    if (st->before < s->last && st->before>0) return 0; 
  46.    if (st->rng_flags && !(s->flags & st->rng_flags)) return 0;
  47.    if (act==A_FORCE) return 1; /* force takes precedence over forgotten */
  48. /* 
  49. if (s->flags & IF_FORGOTTEN)
  50. printf("<%d:%d:%d:%d>",i,spec & (OF_NOFORGET|OF_FORGOTTEN|OF_RETIRED),
  51.                        flags & O_FORGET,
  52.                        s->flags & (IF_FORGOTTEN|IF_RETIRED));
  53. */
  54.    if (!(spec & (OF_NOFORGET|OF_FORGOTTEN)) && (flags & O_FORGET) 
  55.     && (s->flags & IF_FORGOTTEN))
  56.       return 0;
  57.    if (!(spec & (OF_NOFORGET|OF_RETIRED)) && (s->flags & IF_RETIRED)) 
  58.       return 0;
  59.    if (!(spec & (OF_NOFORGET|OF_EXPIRED)) && (s->flags & IF_EXPIRED)) 
  60.       return 0;
  61.  
  62.    /* Process NEW limitations */
  63. /* Changed per Russ's suggestion
  64.    if ((spec & OF_NEWRESP) && p->nr && (abs(p->nr) < s->nr)) return 1;
  65. */
  66.    if ((spec & OF_NEWRESP) && p->nr && (p->last < s->last)) return 1;
  67.    if ((spec & OF_BRANDNEW) && (!p->nr && s->nr)
  68.     && (p->last < s->last))  return 1;
  69.    if  (spec & (OF_NEWRESP|OF_BRANDNEW)) return 0;
  70.    if ((spec & OF_UNSEEN) && p->nr) return 0;
  71.    if ((spec & OF_FORGOTTEN) && !(s->flags & IF_FORGOTTEN)) return 0;
  72.    if ((spec & OF_RETIRED) && !(s->flags & IF_RETIRED)) return 0;
  73.  
  74.    /* if (spec & OF_NEXT) spec |= OF_NONE; */
  75.    return 1;
  76. }
  77.  
  78. /*****************************************************************************/
  79. /* MARK A RANGE OF ITEMS TO BE ACTED UPON                                    */
  80. /*****************************************************************************/
  81. static void                     /* RETURNS: (nothing) */
  82. markrange(bg,nd,act,sum,st,val) /* ARGUMENTS: */
  83. short      bg;                  /*    Beginning of range */
  84. short      nd;                  /*    End of range */
  85. short      val;                 /*    Action value to set */
  86. char       act[MAX_ITEMS];      /*    Action array to fill in */
  87. sumentry_t sum[MAX_ITEMS];      /*    Summary of item info    */
  88. status_t  *st;                  /*    Conference statistics   */
  89. {
  90.    short j;
  91.  
  92.    if (bg<st->i_first)
  93.       printf("Item #%d is too small (first %d)\n",bg,st->i_first);
  94.    else if (nd>st->i_last)
  95.       printf("Item #%d is too big (last %d)\n",nd,st->i_last);
  96.    else {
  97.       for (j=bg; j<=nd; j++) 
  98.          if (sum[j-1].flags) act[j-1]=val;
  99.       if (bg==nd && !sum[bg-1].flags)
  100.          printf("No such item!\n");
  101.    }
  102. }
  103.  
  104. /*****************************************************************************/
  105. /* CONVERT A TOKEN TO AN INTEGER                                             */
  106. /*****************************************************************************/
  107. short                /* RETURNS: item number     */
  108. get_number(token,st) /* ARGUMENTS:                */
  109. char      *token;    /*    Field to process      */
  110. status_t  *st;       /*    Conference statistics */
  111. {
  112.    short a,b;
  113.  
  114.    if (match(token,"fi_rst")
  115.     || match(token,"^"))      return st->i_first;
  116.    if (match(token,"l_ast")
  117.     || match(token,"$"))      return st->i_last;
  118.    if (match(token,"th_is")
  119.     || match(token,"cu_rrent")
  120.     || match(token,"."))      return st->i_current;
  121.    if (sscanf(token,"%hd.%hd",&a,&b)==2) {
  122.       if (b>=0 && b<sum[a-1].nr) st->r_first = b;
  123.       return a;
  124.    }
  125.    return atoi(token);
  126. }
  127.  
  128. void
  129. rangearray(argv,argc,start,fl,act,sum,st) 
  130. char     **argv;
  131. int        argc,start;
  132. short     *fl;                   /*    Flags to use */
  133. char       act[MAX_ITEMS];       /*    Action array to fill in */
  134. sumentry_t sum[MAX_ITEMS];       /*    Item summary info array */
  135. status_t  *st;                   /*    Conference statistics */
  136. {
  137.    short i;
  138.  
  139.    for (i=start; i<argc; i++) {
  140.       if (match(argv[i],"si_nce") || match(argv[i],"S="))
  141.          st->since  = since(argc,argv,&i);
  142.       else if (match(argv[i],"before") || match(argv[i],"B="))
  143.          st->before = since(argc,argv,&i);
  144.       else if (match(argv[i],"by") || match(argv[i],"A=")) {
  145.          if (i+1 >= argc) 
  146.             printf("Invalid author specified.\n");
  147.          else 
  148.             strcpy(st->author, argv[++i]);
  149.       } else if (!match(argv[i],"F=")) /* skip "F=" */
  150.          rangetoken(argv[i],fl,act,sum,st);
  151.    }
  152. }
  153.  
  154. /*****************************************************************************/
  155. /* PARSE ONE FIELD OF A RANGE SPECIFICATION                                  */
  156. /*****************************************************************************/
  157. void                             /* RETURNS: (nothing) */
  158. rangetoken(token,flg,act,sum,st) /* ARGUMENTS: */
  159. char      *token;                /*    Field to process */
  160. short     *flg;                  /*    Flags to use */
  161. char       act[MAX_ITEMS];       /*    Action array to fill in */
  162. sumentry_t sum[MAX_ITEMS];       /*    Item summary info array */
  163. status_t  *st;                   /*    Conference statistics */
  164. {
  165.    short fl,a,b,c;
  166.    char  buff[MAX_LINE_LENGTH],*bp,**arr;
  167.  
  168.    if (flags & O_DEBUG)
  169.       printf("rangetoken: '%s'\n",token);
  170.    if (bp=expand(token,DM_PARAM)) {
  171.       arr = explode(bp," ");
  172.       rangearray(arr,xsizeof(arr),0,flg,act,sum,st);
  173.       xfree(arr);
  174.       return;
  175.    }
  176.    fl = *flg;
  177.  
  178.    if        (match(token,"a_ll")
  179.     ||        match(token,"*")) { 
  180.       markrange(st->i_first, st->i_last,act,sum,st,A_COVER);
  181.       fl |=  OF_RANGE; /* items specified */
  182.    } else if (match(token,"nex_t")) {    /*  fl |=  OF_NEXT; */
  183.       markrange((short)(st->i_current+1),st->i_last,act,sum,st,A_COVER);
  184.       fl |=  OF_RANGE; /* KKK */
  185.    } else if (match(token,"pr_evious")) {    fl |=  /* OF_NEXT | */ OF_REVERSE;
  186.       markrange(st->i_first,(short)(st->i_current-1),act,sum,st,A_COVER);
  187.       fl |=  OF_RANGE; /* KKK */
  188.    } else if (match(token,"n_ew")) {         fl |=  OF_BRANDNEW | OF_NEWRESP;
  189.    } else if (match(token,"nof_orget")) {    fl |=  OF_NOFORGET;
  190.    } else if (match(token,"p_ass")) {        fl |=  OF_PASS;
  191.    } else if (match(token,"d_ate")) {        fl |=  OF_DATE;
  192.    } else if (match(token,"nor_esponse")) {  fl |=  OF_NORESPONSE;
  193.    } else if (match(token,"u_id")) {         fl |=  OF_UID;
  194.    } else if (match(token,"nod_ate")) {      fl &= ~OF_DATE;
  195.    } else if (match(token,"nou_id")) {       fl &= ~OF_UID;
  196.    } else if (match(token,"bra_ndnew")) {    fl |=  OF_BRANDNEW;
  197.    } else if (match(token,"newr_esponse")) { fl |=  OF_NEWRESP;
  198.    } else if (match(token,"r_everse")) {     fl |=  OF_REVERSE;
  199.    } else if (match(token,"s_hort")) {       fl |=  OF_SHORT;
  200.    } else if (match(token,"nop_ass")) {      fl &= ~OF_PASS;
  201.    } else if (match(token,"nu_mbered")) {    fl |=  OF_NUMBERED;
  202.    } else if (match(token,"nonu_mbered")) {  fl &= ~OF_NUMBERED;
  203.    } else if (match(token,"unn_umbered")) {  fl &= ~OF_NUMBERED;
  204.    } else if (match(token,"o_ld")) {         /* KKK */
  205.    } else if (match(token,"exp_ired")) {     fl |=  OF_EXPIRED;
  206.    } else if (match(token,"ret_ired")) {     fl |=  OF_RETIRED;
  207.    } else if (match(token,"for_gotten")) {   fl |=  OF_FORGOTTEN;
  208.    } else if (match(token,"un_seen")) {      fl |=  OF_UNSEEN;
  209.    } else if (match(token,"linked")) {       st->rng_flags |= IF_LINKED;
  210.    } else if (match(token,"frozen")) {       st->rng_flags |= IF_FROZEN;
  211.    } else if (match(token,"force_response")
  212.       ||      match(token,"force_respond")){ /* KKK */
  213.    } else if (match(token,"respond")) {      /* KKK */
  214.    } else if (match(token,"form_feed")       
  215.       ||      match(token,"ff")) {           /* KKK */
  216.    } else if (match(token,"lo_ng")) {        fl &= ~OF_SHORT;
  217.    } else if (token[0]=='"') { /* "string" */
  218.       strcpy(st->string,token+1);
  219.       st->string[ strlen(token)-2 ]='\0';
  220.    } else if (strchr(token,',')) {
  221.       arr = explode(token,",");
  222.       rangearray(arr,xsizeof(arr),0,flg,act,sum,st);
  223.       xfree(arr);
  224.       return;
  225.    } else if (token[0]=='-') {
  226.       a = get_number(token+1,st);
  227.       markrange(st->i_first,a,act,sum,st,A_COVER);
  228.       fl |= OF_RANGE; /* range specified */
  229.    } else if (token[strlen(token)-1]=='-') {
  230.       strcpy(buff,token);
  231.       buff[strlen(buff)-1]='\0';
  232.       a = get_number(buff,st);
  233.       markrange(a,st->i_last,act,sum,st,A_COVER);
  234.       fl |= OF_RANGE; 
  235.    } else if (bp=strchr(token,'-')) {
  236.       strncpy(buff,token,bp-token);
  237.       buff[bp-token]='\0';
  238.       a = get_number(buff,st);
  239.       b = get_number(bp+1,st);
  240.       if (b<a) { c=b; b=a; a=c; fl ^= OF_REVERSE; }
  241.       markrange(a,b,act,sum,st,A_COVER);
  242.       fl |= OF_RANGE;
  243. /*
  244.    } else if (sscanf(token,"-%hd",&a)==1) { 
  245.       markrange(st->i_first,a,act,sum,st,A_COVER);
  246.       fl |= OF_RANGE; 
  247.    } else if (sscanf(token,"%hd-%hd",&a,&b)==2) { 
  248.       if (b<a) { c=b; b=a; a=c; fl ^= OF_REVERSE; }
  249.       markrange(a,b,act,sum,st,A_COVER);
  250.       fl |= OF_RANGE;
  251.    } else if (sscanf(token,"%hd%c",&a,&ch)==2 && ch=='-') { 
  252.       markrange(a,st->i_last,act,sum,st,A_COVER);
  253.       fl |= OF_RANGE; 
  254.    } else if (sscanf(token,"%hd",&a)==1) { 
  255.       markrange(a,a,act,sum,st,A_FORCE);
  256.       fl |= OF_RANGE; 
  257. */
  258.    } else if (a=get_number(token,st)) {
  259.       markrange(a,a,act,sum,st,A_FORCE);
  260.       fl |= OF_RANGE; 
  261.    } else {
  262.       strcpy(st->string,token);
  263. /* KKK printf("Bad token type in getrange\n"); */
  264.    }
  265.    *flg = fl;
  266. }
  267.  
  268. time_t
  269. since(argc,argv,ip)
  270. int    argc;
  271. char **argv;
  272. short *ip;
  273. {
  274.    short i,j,start=0;
  275.    char buff[MAX_LINE_LENGTH],*ptr;
  276.    int where[MAX_ARGS];
  277.    time_t t;
  278.  
  279.    i = *ip + 1;
  280.    if (i>=argc) {
  281.       printf("Bad date near \"<newline>\"\n");
  282.       return LONG_MAX; /* process nothing */
  283.    }
  284.    /* if (!strnicmp(argv[i],"S=",2) || !strnicmp(argv[i],"B=",2)) start+=2; */
  285.    if (argv[i][start]=='"') {
  286.       if (argv[i][ strlen(argv[i])-1 ]=='"')
  287.           argv[i][ strlen(argv[i])-1 ]='\0';
  288.       getdate(&t,argv[i]+start+1);
  289.    } else {
  290.       where[i]=0;
  291.       strcpy(buff,argv[i]+start);
  292.       for (j=i+1; j<argc; j++) {
  293.      strcat(buff," ");
  294.          where[j]=strlen(buff);
  295.      strcat(buff,argv[j]);
  296.       }
  297.       ptr=getdate(&t,buff);
  298.       for ( ; ptr-buff > where[i] && i<argc; i++);
  299.       i--;
  300.    }
  301.    if (flags & O_DEBUG)
  302.       printf("Since set to %s",ctime(&t));
  303.    *ip = i;
  304.    return t;
  305. }
  306.  
  307. void
  308. rangeinit(st,act)
  309. status_t *st;
  310. char act[MAX_ITEMS];
  311. {
  312.    short i;
  313.  
  314.    st->string[0]= st->author[0] = '\0';
  315.    st->since    = st->before = st->opt_flags = 0;
  316.    st->rng_flags = 0;
  317. /* flags |= O_FORGET;  commented out 8/18 since it breaks 'set noforget;r' */
  318.    for (i=0; i<MAX_ITEMS; i++) act[i]=0;
  319. }
  320.  
  321. /*****************************************************************************/
  322. /* PARSE ONE FIELD OF A RANGE SPECIFICATION                                  */
  323. /* Note that we need sum passed in because linkfrom does ranges in other     */
  324. /* conference                                                                */
  325. /*****************************************************************************/
  326. void                            /* RETURNS: (nothing) */
  327. range(argc,argv,fl,act,sum,st,bef)  /* ARGUMENTS: */
  328. int        argc;                /*    Number of arguments */
  329. char     **argv;                /*    Argument list       */
  330. short     *fl;                  /*    Flags to use */
  331. char       act[MAX_ITEMS];      /*    Action array to fill in */
  332. sumentry_t sum[MAX_ITEMS];      /*    Item summary info array */
  333. status_t  *st;                  /*    Conference statistics */
  334. int        bef;
  335. {
  336.    rangearray(argv,argc,bef+1,fl,act,sum,st);
  337. }
  338.