User:Antigng-bot/closeafd

维基百科,自由的百科全书
struct nm
{
	char title[100];
	struct text *ln;
	struct text *la;
	int section;
	int count;
	struct nm next;
};
/* 
  存储未关闭存废讨论的结构,ln是分割线、section以前的内容,la是以后的内容。title为标题,section为章节编号,count为标题中的等号数。
*/
struct text 
{
	char *line;
	struct text *next;
};
struct nm *fetchtitle()
{
       /*
        这个函数从存储存废讨论页面源码的结构中获取未关闭的讨论,储存到一个链表。为方便起见,这里假设文件"a.txt"存储着页面源码。每次循环从文件中读入一个字符,根据读入
        的字符判断位置status,无需回溯。status的含义:
        -1:位于页面大标题之前 -2:位于大标题左边的等号中 -3:位于大标题中间 -4:位于大标题右边的等号中 0:位于正文已关闭的存废讨论文本中 1:位于提删项目标题左边的等号中
        2:位于提删项目标题中间,尚未读到 "[[" 3:位于提删标题中的内链里 4:已读完内链,尚未读到右边的等号 5:位于提删项目标题右边的等号中 
        6:读完提删标题,确定不是关注度的标题,正检查有无delh 7:未关闭存废讨论的正文部分
        在读取存废讨论正文的时候,还需要注意分割线和section标签,其上、下内容应分开存储。
        */
	int status=-1; //读取页面的状态
	int nota=0;//关注度状态
	int section=0;//分割线状态
	int lf=0;//换行
	const char *not="notability",*sec="<section",*del="{{delh|",*DEL="{{DELH|";//需要匹配的字符串
	const int notl=strlen(not),secl=strlen(sec),dell=strlen(del);//它们的长度
	int notc=0,secc=0,delc=0;//进行匹配时的位置
	char title [500];//存储页面标题
	int titlec=0;//读取标题的位置
	struct nm *head=0,*temp=0,*pre=0;
	struct text *temp1=0,*pre1=0,*temp2=0,*pre2=0;
	char ch=0;//读入的字符
	int leq=0,req=0;//用于检查等号是否匹配
	int deq=0;//大标题中等号的个数
	int bra=0;//匹配括号
	char buff[10*1024]={0};//一行
	int buffc;//行中的位置
	int countsec=-2;//section number
	int i;
	FILE *f;
	f=fopen("a.txt","r+");
	while(!feof(f))
	{
        if(ch=='\n') lf=1;
		else lf=0;
		ch=fgetc(f);
		switch(status)
		{
		case -1:
			if(ch=='='&&lf) 
			{
				status=-2;
				leq++;
			}
			break;
		case -2:
			if(ch=='=')
			{
				leq++;
			}
			else status=-3;
			break;
		case -3:
			if(ch=='=')
			{
				req=0;req++;
				status=-4;
			}
			break;
		case -4:
			if(ch=='=')
			{
				req++;
			}
			else
			{
				countsec++;
				if(leq!=req) return -1;//左右括号不匹配
				deq=leq;
				leq=req=0;
				status=0;
			}
			break;
		case 0:
			if(ch=='='&&lf)
			{
				status=1;
				leq=0;
				leq++;
			}
			break;
		case 1:
			if(ch=='=')
			{
				leq++;
			}
			else {
				status=2;
				bra=0;
				if(ch=='[') bra++;
			}
			break;
		case 2:
			switch(bra)
			{
			case 0:if(ch=='[') bra=1;
				else bra=0;
				break;
			case 1:if(ch=='[') bra=0;
				titlec=0;
                status=3;
				break;
			}
			if(notc==notl)
			{
				notc=0;
			  if(nota==0)	nota=1;
			   else return -2;//关注度嵌套,神经病
			}
			else if(not[notc]==ch)
			{
				notc++;
			}
			else notc=0;//根据kmp算法,不存在回溯的可能性
			if(ch=='=') {status=5;req=0;req++;}
			break;
		case 3:
			if(!(ch==':'&&titlec==0))
			{
                if(ch!=']')
				{
				   title[titlec]=ch;
				   titlec++;
				   title[titlec]=0;
				}
				else status=4;
			}
			break;
		case 4:
			if(ch=='=') 
			{
				status=5;
				req=0;
				req++;
			}
			break;
		case 5:
			if(ch=='=')
			{
				req++;
			}
			else 
			{
				countsec++;
				if(leq!=req) 
					return -1;
				if(nota==0)
				{
					 status=6;
				}
				else if(nota==1)
				{
					nota=2;
					status=0;
				}
				else 
				{
					if(leq>=2+deq) status=6;
					else 
					{
						nota=0;
						status=6;
					}
				}

			}
			break;
		case 6:
			if(ch!='\n'&&ch!=' ')
			{
				if(lf&&!delc)
				{
					if(ch!='{') {status=7;}
					else 
					{
						delc++;
				
					}
				}
				else if(delc<dell)
				{
					if(ch!=del[delc]&&ch!=DEL[delc])
					{
						status=7;
					}
					else delc++;
				}
				else if(delc==dell)
				{
					status=0;
					delc=0;
				}
			}
			if(status==7)
			{
				if(!head)
				{
					temp=(struct nm*)malloc(sizeof(struct nm));
					head=pre=temp;
					temp->next=0;
				}
				else
				{
					pre=temp;
					temp=(struct nm*)malloc(sizeof(struct nm));
					temp->next=0;
					pre->next=temp;
				}
				temp->section=countsec;
				temp->count=leq;
				strcpy(temp->title,title);
				temp->la=0;
				temp->ln=0;
				buffc=0;
				buff[buffc]=0;
				section=0;
				if(delc)
				{
					for(i=0;i<delc;i++)
					{
						buff[buffc]=del[i];
						buffc++;
						buff[buffc]=0;
					}
					delc=0;
				}
				buff[buffc]=ch;
				buffc++;
				buff[buffc]=0;
				
			}
			break;
		case 7:
			if(lf)
			{
				if(section)
				{
					if(!temp->la)
					{
						temp->la=(struct text *)malloc(sizeof(struct text));
						pre2=temp2=temp->la;
						temp2->next=0;
						temp2->line=(char *)malloc(buffc+5);
						strcpy(temp2->line,buff);
					}
					else
					{
						pre2=temp2;
						temp2=(struct text *)malloc(sizeof(struct text));
						temp2->next=0;
						pre2->next=temp2;
						temp2->line=(char *)malloc(buffc+5);
						strcpy(temp2->line,buff);
					}
				}
				else
					{
					if(!temp->ln)
					{
						temp->ln=(struct text *)malloc(sizeof(struct text));
						pre1=temp1=temp->ln;
						temp1->next=0;
						temp1->line=(char *)malloc(buffc+5);
						strcpy(temp1->line,buff);
					}
					else
					{
						pre1=temp1;
						temp1=(struct text *)malloc(sizeof(struct text));
						temp1->next=0;
						pre1->next=temp1;
						temp1->line=(char *)malloc(buffc+5);
						strcpy(temp1->line,buff);
					}
				}
				buffc=0;
				buff[buffc]=0;
			}


			if(ch!='='||!lf)
			{
				if(!section)
				{
					if(lf&&ch=='-') section=1;
					else if(lf&&!secc&&ch=='<')
					{
						secc++;
					}
					else if(secc<secl)
					{
						if(ch==sec[secc])
						{
							secc++;
						}
						else secc=0;
					}
					else if(secc==secl)
					{
						section=1;
						secc=0;
					}
				}
				buff[buffc]=ch;
				buffc++;
				buff[buffc]=0;
			}
			else
			{
				leq=0;
				leq++;
				status=1;
			}
			break;
		}
		
	}
	fclose(f);
        if(buffc>1) //如果没有读完一行,就没东西了,需要把buff里面的内容写入。
	{
		buffc--; //在这个例子中,存储存废讨论源码的介质是文件,末尾有一个结束符需要删去。
		buff[buffc]=0;
		if(section)
				{
					if(!temp->la)
					{
						temp->la=(struct text *)malloc(sizeof(struct text));
						pre2=temp2=temp->la;
						temp2->next=0;
						temp2->line=(char *)malloc(buffc+5);
						strcpy(temp2->line,buff);
					}
					else
					{
						pre2=temp2;
						temp2=(struct text *)malloc(sizeof(struct text));
						temp2->next=0;
						pre2->next=temp2;
						temp2->line=(char *)malloc(buffc+5);
						strcpy(temp2->line,buff);
					}
				}
				else
					{
					if(!temp->ln)
					{
						temp->ln=(struct text *)malloc(sizeof(struct text));
						pre1=temp1=temp->ln;
						temp1->next=0;
						temp1->line=(char *)malloc(buffc+5);
						strcpy(temp1->line,buff);
					}
					else
					{
						pre1=temp1;
						temp1=(struct text *)malloc(sizeof(struct text));
						temp1->next=0;
						pre1->next=temp1;
						temp1->line=(char *)malloc(buffc+5);
						strcpy(temp1->line,buff);
					}
				}
				buffc=0;
				buff[buffc]=0;
	}
	return head;
}

int closeafd(struct nm *afdlist,int n,int action,char *target,char *comment,struct nm **newhead,int notability)
{
	int flag=0,res;
	struct nm *temp,*pre;
	struct text *tx,*txp;
	*newhead=afdlist;
	if(!afdlist) return -1;
	pre=temp=afdlist;
	flag=0;
	while(temp)
	{
		if(temp->section>n) return -2;
		if(temp->section==n)
		{
			flag=1;
			break;
		}
		pre=temp;
		temp=temp->next;
	}
	if(!flag) return -2;
	res=check(temp->title);
	if(res==1) return -3;
	if(action==1)
	{
		res=check(target);
		if(res==1) return -4;
	}
	switch(action)
	{
		case 0:removetemp(temp->title,1);
		       break;
		case 1:redirect(temp->title,target,notability);
		       break;	
    case 2:removetemp(temp->title,0);
		       break;
    case 3:removetemp(temp->title,0);
           break; 
	}
	addtalk(temp->title,action);
  closingdebate(temp,action,comment);
  if(temp==afdlist) *newhead=temp->next;
  else pre->next=temp->next;
  tx=temp->ln;
  while(tx)
  {
  	txp=tx;
  	tx=tx->next;
  	free(txp);
	}
	tx=temp->la;
  while(tx)
  {
  	txp=tx;
  	tx=tx->next;
  	free(txp);
	}
	free(temp);
	return 0;
}