⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macedon-transition.c

📁 这是一个著名的应用层组播中间件的源码
💻 C
字号:
//Copyright (c) 2004, Charles Killian, Adolfo Rodriguez, Dejan Kostic, Sooraj Bhat, and Amin Vahdat//All rights reserved.////Redistribution and use in source and binary forms, with or without//modification, are permitted provided that the following conditions are met:////   * Redistributions of source code must retain the above copyright//     notice, this list of conditions and the following disclaimer.//   * Redistributions in binary form must reproduce the above copyright//     notice, this list of conditions and the following disclaimer in//     the documentation and/or other materials provided with the//     distribution.//   * Neither the names of Duke University nor The University of//     California, San Diego, nor the names of its contributors//     may be used to endorse or promote products derived from//     this software without specific prior written permission.////THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE//DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE//FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL//DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR//SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 POSSIBILITY OF SUCH DAMAGE./* macedon-transition.c *//* * For MACEDON code generation * * Adolfo Rodriguez *//* includes */#include <fnmatch.h>#include <stdio.h>#include <string.h> /* for strcmp(), strdup() */#include "macedon-conv.h"#include "macedon-conv-utils.h"/* imports */extern char *protocol_name;extern FILE *hfile, *cfile, *cfilefuncs, *cfile2;extern node_type *my_node_types;extern message *my_messages;extern transport *my_transports;extern neighbor_type *my_neighbor_types;extern declare *my_periphs;extern declare *my_locals;extern state *my_states;extern timer *my_timers;extern constant *my_constants;extern object_replace *my_replaces;extern api_demux* apidemux;extern msg_demux* msglist;extern char *base_name;extern int API_specified[API_num_types];extern int trans_API;extern int trans_API_index;extern int trans_locking;extern int init_func;extern int tracing;char* expr_to_human_readable(char* expr){    char ch;    char *temp,*res;    if (strcmp(expr,"any")==0 || strcmp(expr,"*")==0)		return strdup("any");     res = (char*)malloc(128);    temp = res;    while (ch = *expr)    {		switch (ch)		{		case '!':			sprintf(temp,"%s","not_");			temp += 4;			break;		case '(':			sprintf(temp,"%s","op_");			temp += 3;			break;		case '|':			sprintf(temp,"%s","or_");			temp += 3;			break;		case ')':			sprintf(temp,"%s","cp_");			temp += 3;			break;		case '?':			sprintf(temp,"%s","qm_");			temp += 3;			break;		case '*':			sprintf(temp,"%s","star_");			temp += 5;			break;		default:			while (ch && (isalnum(ch) || ch == '_'))			{				*temp++ = ch;				ch = *++expr;			}			*temp++ = '_';			expr--;			break;		}		expr++;    }    *--temp = 0;    return res;}void transition_locking (char *type){  if (!strcmp(type, "none"))    trans_locking = LOCK_NONE;  else if (!strcmp(type, "read"))    trans_locking = LOCK_READ;  else if (!strcmp(type, "write"))    trans_locking = LOCK_WRITE;  else    trans_locking = LOCK_UNSPECIFIED;}void add_transition(char *instate, char *func, char *name){  int i;  state *temps;  char * temp ;  char *state ;  char *base_state;  char *timer_name;  char *real_timer_name;  char real_name[100];  timer *tempt;  timer_demux *temptd;  api_demux *tempad;  declare *tempp;  node_type *tempnt;  message *mymsg;  FILE *outcfile;  int flags_notted_tran;  int the_first;  char *temp_str;  msg_demux* msgd;#ifdef GEN_TRACE  printf("Adding transition %s %s %s\n", instate, func, name);  fflush(NULL);#endif    /**   * Process the state expression.  The human-readable name   * goes in 'state', the expression stays in 'instate'   * 'base_state' is unused (Jul 23 2003... Sooraj)   * pattern matching is done later in this function   * and in end_agent(), too.   **/    state = expr_to_human_readable(instate);  /** this block MUST come after the call to   * expr_to_human_readable() */  if (instate[0]=='!') {    if (instate[1] != '(') {      temp_str = (char*)malloc(400);      sprintf(temp_str,"!(%s)",instate+1);      instate = temp_str;    }  }  else {    temp_str = (char*)malloc(400);    sprintf(temp_str,"@(%s)",instate);    instate = temp_str;  }    if (strncmp(func, "recv", 4) == 0 || strncmp(func, "forward", 7) == 0) {    int recv_flag;    if (strncmp(func, "recv", 4) == 0) {      fprintf(hfile, "  void %s_%s_%s(Packet *);\n", state, func, name);  #ifdef PROFILE_AGENTS      fprintf(hfile, "  int %s_%s_%s_count;\n", state, func, name);        fprintf(hfile, "  double %s_%s_%s_total;\n", state, func, name);  #endif      outcfile = cfile;      recv_flag = 1;    }    else {      fprintf(hfile, "  int %s_%s_%s(Packet *);\n", state, func, name);  #ifdef PROFILE_AGENTS      fprintf(hfile, "  int %s_%s_%s_count;\n", state, func, name);        fprintf(hfile, "  double %s_%s_%s_total;\n", state, func, name);  #endif      outcfile = cfile2;      recv_flag = 3;    }        sprintf(real_name, "%s_message_%s", protocol_name, name);    mymsg = lookup_message(real_name);        if (mymsg==0) {      printf("Error in finding message %s specified in transition.\n", real_name);      exit(46);    }            fprintf(outcfile, "  if(!processed && recv_hdr%s->%s_mf_.mh_type_ ==  %s_message_%s && (\n",	    protocol_name, protocol_name, protocol_name, name);        if (strcmp(state,"any")==0) {      fprintf(outcfile,"true");    }    else {      the_first = 1;      temps = my_states;      while (temps) {	if (fnmatch(instate,temps->base_state_name,FNM_EXTMATCH)==0) { 			  if (!the_first) fprintf(outcfile, " ||");	  else the_first = 0;	  fprintf(outcfile, " fsm == %s ",temps->state_name);	}	temps = temps->next;      }    }    fprintf(outcfile,"))\n");        fprintf(outcfile, "      {\n");    fprintf(outcfile, "        processed = 1;\n");          if (tracing)       fprintf(outcfile, "        dump_packet(pkt, 0, %d);\n", recv_flag);    if (trans_locking == LOCK_NONE) { // no locking at all    }    else if (trans_locking == LOCK_READ) { // read locking semantics      fprintf(outcfile, "  Lock_Read();\n");    }    else if (trans_locking == LOCK_WRITE ||	     trans_locking == LOCK_UNSPECIFIED) { // write locking semantics      fprintf(outcfile, "  Lock_Write();\n");    }    #ifdef PROFILE_AGENTS    fprintf(outcfile, "  double _starttime = Scheduler::instance().clock();\n");#endif    if (strncmp(func, "recv", 4) == 0)       fprintf(outcfile, "        %s_%s_%s(pkt);\n", state, func, name);    else {      fprintf(outcfile, "        retval = %s_%s_%s(pkt);\n", state, func, name);      if (tracing) {	fprintf(outcfile, "        if(!retval)\n");	fprintf(outcfile, "          dump_packet(pkt, 0, 2);\n");      }    }    msgd = (msg_demux*)malloc(sizeof(msg_demux));    msgd->next = msglist;    msgd->msgfunc = (char*) malloc(strlen(state)+strlen(func)+strlen(name)+3);    sprintf(msgd->msgfunc, "%s_%s_%s", state, func, name);    msglist = msgd;#ifdef PROFILE_AGENTS    fprintf(outcfile, "  %s_%s_%s_count++;\n", state, func, name);    fprintf(outcfile, "  %s_%s_%s_total+=Scheduler::instance().clock()-_starttime;\n",state, func, name);#endif    if (trans_locking == LOCK_NONE) { // no locking at all    }    else { // locking      fprintf(outcfile, "  Unlock();\n");    }    fprintf(outcfile, "      }\n");    fprintf(outcfile, "\n");        if (strncmp(func, "recv", 4) == 0)       fprintf(cfilefuncs, "void %s_Agent::%s_%s_%s(Packet *pkt)\n", protocol_name, state, func, name);      else      fprintf(cfilefuncs, "int %s_Agent::%s_%s_%s(Packet *pkt)\n", protocol_name, state, func, name);      fprintf(cfilefuncs, "{\n");    fprintf(cfilefuncs, "  double curtime = Scheduler::instance().clock();\n");#ifdef ALLINONEHDR    fprintf(cfilefuncs, "  unpack_pkt();\n");      #else    fprintf(cfilefuncs, "  unpack_pkt(%s);\n", name);  #endif      }  else if (strncmp(func, "timer", 5) == 0) {    timer_name = name;    real_timer_name = conv_name_timer(timer_name);    tempt = lookup_timer(real_timer_name);        temptd = (timer_demux *) malloc (sizeof(timer_demux));    temptd->state = (char *) malloc (strlen(instate)+1);        /** send it the expr, to evaluate later (in end_agent()) **/    sprintf(temptd->state, "%s", instate);     temptd->locking = trans_locking;    temptd->func = (char *) malloc (strlen(state)+strlen(func)+strlen(name)+3);    sprintf(temptd->func, "%s_%s_%s", state, func, timer_name);    temptd->next = tempt->demux;      tempt->demux = temptd;        fprintf(hfile, "  void %s_%s_%s();\n", state, func, timer_name);  #ifdef PROFILE_AGENTS    fprintf(hfile, "  int %s_%s_%s_count;\n", state, func, name);      fprintf(hfile, "  double %s_%s_%s_total;\n", state, func, name);  #endif        fprintf(cfilefuncs, "void %s_Agent::%s_%s_%s()\n", protocol_name, state, func, timer_name);      fprintf(cfilefuncs, "{\n");    fprintf(cfilefuncs, "  double curtime = Scheduler::instance().clock();\n");  }  else if (strncmp(func, "API", 3) == 0) {    for (i=0; i<API_num_types; i++) {      if (strcmp(name, API_types[i])==0) {        API_specified[i]=1;        fprintf(hfile, "    %s %s_%s_%s%s;\n", API_returns[i], state, func, name, API_protoparams[i]);  #ifdef PROFILE_AGENTS        fprintf(hfile, "    int %s_%s_%s_count;\n", state, func, name);          fprintf(hfile, "    double %s_%s_%s_total;\n", state, func, name);  #endif        fprintf(cfilefuncs, "%s %s_Agent::%s_%s_%s%s\n", API_returns[i], protocol_name, state, func, name, API_protoparams[i]);          tempad = (api_demux *) malloc (sizeof(api_demux));        tempad->state = (char *) malloc (strlen(instate)+1);	        /** send it the expr, to evaluate later (in end_agent()) **/        sprintf(tempad->state, "%s", instate);         tempad->func = (char *) malloc (strlen(state)+strlen(func)+strlen(name)+strlen(API_params[i])+3);        sprintf(tempad->func, "%s_%s_%s%s", state, func, name, API_params[i]);        tempad->func2 = (char *) malloc (strlen(state)+strlen(func)+strlen(name)+3);        sprintf(tempad->func2, "%s_%s_%s", state, func, name);        tempad->api = (char *) malloc (strlen(name)+2);        sprintf(tempad->api, "%s", name);        tempad->next = apidemux;        tempad->API_index = i;        tempad->locking = trans_locking;        apidemux = tempad;        break;      }    }    if (i==API_num_types)  // ran off the end      {	printf("Error:  Specified API function %s, but that is not part of MACEDON API.\n", name);	exit(6);      }        fprintf(cfilefuncs, "{\n");    trans_API = 1;    trans_API_index = i;    /*     if (trans_locking == LOCK_NONE) { // no locking at all */    /*     } */    /*     else if (trans_locking == LOCK_READ) { // read locking semantics */    /*       fprintf(cfilefuncs, "  Lock_Read();\n"); */    /*     } */    /*     else if (trans_locking == LOCK_WRITE) { // write locking semantics */    /*       fprintf(cfilefuncs, "  Lock_Write();\n"); */    /*     } */    /*     else {  // unspecified, take default behavior */    /*       if (API_sendsdata[i] == 1) { */    /* 	fprintf(cfilefuncs, "  if (size == -1) return -1;\n"); */    /* 	if(API_needslocking[i] == 1) { */    /* 	  fprintf(cfilefuncs, "  Lock_Read();\n"); */    /* 	} */    /*       } */    /*       else { */    /* 	if(API_needslocking[i] == 1) { */    /* 	  fprintf(cfilefuncs, "  Lock_Write();\n"); */    /* 	} */    /*       } */    /*     } */    if (API_sendsdata[i] == 1)       fprintf(cfilefuncs, "  int return_code = 0;\n");    fprintf(cfilefuncs, "  double curtime = Scheduler::instance().clock();\n");    if (strcmp(name, "init")==0)    {      if (!base_name) {        transport *temptr = my_transports;        while (temptr) {          if (temptr->type)            fprintf(cfilefuncs, "  %s->register_receiver(this, (tr_handler)&%s_Agent::recv_from_pipe, (er_handler)&%s_Agent::macedon_upcall_ext);\n", temptr->over, protocol_name, protocol_name);          temptr = temptr->next;        }      }      init_func=1;      tempp = my_periphs;      while (tempp)      {        tempnt = my_node_types;        while (tempnt)        {          if (strcmp(tempp->name, tempnt->simple_name) == 0 && tempp->exported)           {            fprintf(cfilefuncs, "  if (here_.addr_ == %s)\n", tempp->name);            fprintf(cfilefuncs, "    node_type = %s;\n", tempnt->type_name);           }          tempnt = tempnt->next;        }        tempp = tempp->next;      }    }  }  else  {    fprintf(hfile, "  void %s_%s_%s();\n", state, func, name);      fprintf(cfilefuncs, "void %s_Agent::%s_%s_%s()\n", protocol_name, state, func, name);      fprintf(cfilefuncs, "{\n");    fprintf(cfilefuncs, "  double curtime = Scheduler::instance().clock();\n");    fprintf(stderr, "Warning: Added transition of unknown type.  HOW DID I GET HERE? Pls fill out a bug report!\n");  }  return;}void done_transition(){  declare *temp;  if (trans_API) {    /*     if (trans_locking == LOCK_NONE) { // no locking at all */    /*     } */    /*     else if (trans_locking == LOCK_WRITE ||  */    /* 	     trans_locking == LOCK_READ || */    /* 	     API_needslocking[trans_API_index] == 1) { // locking semantics */    /*       fprintf(cfilefuncs, "  Unlock();\n"); */    /*     } */    if (API_sendsdata[trans_API_index] == 1) {      fprintf(cfilefuncs, "  return return_code;\n");    }  }    trans_locking = LOCK_UNSPECIFIED; // reset locking flag  if (init_func==1)  {    init_func=0;  }  fprintf(cfilefuncs, "}\n");  fprintf(cfilefuncs, "\n");  temp = my_locals;  while (temp)  {    my_locals = temp->next;    free (temp->type);    free (temp->name);    free (temp);    temp = my_locals;  }  trans_API=0;  return;}  void add_prototype(char* type, char* funcname){#ifdef GEN_TRACE  printf("Adding routine %s %s\n", type, funcname);  fflush(NULL);#endif  fprintf(hfile, "%s %s", type, funcname);  fprintf(cfilefuncs, "%s %s_Agent::%s", type, protocol_name, funcname);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -