コード例 #1
0
ファイル: richdaq.C プロジェクト: krafczyk/AMS
void DAQRichBlock::buildrawnode(integer length,int16u *p){
  try{
#ifdef __INSPECT__
  cout<<endl<<endl<<"RICH EVENT INSPECTOR: buildrawnode"<<endl;
  cout<<endl;
  cout<< " -1(-2) -- LENGTH                   -- "<<length<<" words"<<endl;
  int16u value=*p;
  printf("0       -- 1 0 nodeaddress datatype -- %i %i %i %x\n ",
	 (value&(1<<15))>>15,
	 (value&(1<<14))>>14,
	 (value&(0b0011111111100000))>>5,
	 (value&(0b11111)));

  printf("MASK    -- mask %x \n",*(p-2+length));
  printf("???     -- status %x\n",*(p-1+length));
  StatusParser parsed(*(p-1+length));
  printf("        --  SlaveId %i IsCDP %i is RAW %i isCompressed %i isData %i\n",
	 parsed.slaveId,
	 parsed.isCDP,
	 parsed.isRaw,
	 parsed.isCompressed,
	 parsed.isData);
  cout<<endl<<endl;

  cout<<"DUMPING EVERYTHING "<<endl;
  for(int i=0;i<length;i++) {cout<<"+"<<i<<" ";printf("%x\n",*(p+i));}
#endif

#ifdef __AMSDEBUG
  if(AMSFFKEY.Debug>1){
  cout<<"*** IN DAQRichBlock::buildrawnode "<<endl
      <<" Length "<<length<<endl;
  printf(" DUMP %x %x %x %x %x\n",*(p-1),*p,*(p+1),*(p+2),(*p+3));
  }
#endif

  // In p-1 is the node id and so 
  // In p is the event number p
  // In p+1 the first RDR info (its length)
  Status=kOk;
  if(length<1) Do(kLengthError);

  // This is supposed to be a JINF block: get the status word and check it
  //  StatusParser status(*(p-1+length));
  

  int id=((*(p-1))>>5)&((1<<9)-1);
  
  for(int secondary=0;secondary<2;secondary++)
    for(int side=0;side<RICH_JINFs;side++)
      for(int alias=0;alias<2;alias++)
	if(id==JINFNodes[secondary][side][alias]){
	  // Assume that everything here is primary and decode
	  int offset=0;
	  if(DAQCFFKEY.DAQVersion==1) offset=-2;  // Take into account the JINF-R MASK
	  if(!AMSJob::gethead()->isRealData()) offset=-2;  // Take into account the added JINF-R MASK for MC data
	  DecodeRich(length-1+offset,p+1,side,secondary);
	  break;
	}
  return;
  }catch(int){
    static bool first_call=true;
    if(first_call){
      cout<<"-- Problem in DAQRichBlock::buildrawnode. Ignoring further errors"<<endl;
      first_call=false;
    }
  }


  /*  
  // This is supposed to be a JINF block: get the status word and check it
  StatusParser status(*(p-1+length));
  // if(!status.isData || status.errors || status.isCDP) Do(kDataError);
  if(status.errors || status.isCDP) Do(kDataError);
  
  // Get the JINF number
  uint id=status.slaveId;  
  int JINF=-1;
  for(int i=0;i<RICH_JINFs;i++) if(JINFId[i]==id) {JINF=i;break;}
  if(JINF==-1) Do(kJINFIdError);
  

  // Assume that everything here is primary and decode
  DecodeRich(length,p,JINF,0);
  */
}
コード例 #2
0
ファイル: richdaq.C プロジェクト: krafczyk/AMS
void DAQRichBlock::DecodeRich(integer length,int16u *p,int side,int secondary){
  //
  // This functions perform the actual decoding with the information 
  // of the side and if it is a primary of secondary block 
  //

  int16u *pointer=p;

  int CDPFound;          // Counter for the number of CDP found
  int low_gain[RICH_PMTperCDP][RICnwindows];       // Buffer to store low gain information just in case it is needed
  for(CDPFound=0;;CDPFound++){
#ifdef __AMSDEBUG__
    if(AMSFFKEY.Debug>1)
    cout<<"Pointer at "<<pointer-p<<" fence in "<<length-1<<" fence content "<<*(p-1+length)<<endl; 
#endif

    if(pointer>=p-1+length) break;   // Last fragment processed       
    
    FragmentParser cdp(pointer);
    if(cdp.status.errors) Do(kCDPError);

    int CDP=cdp.status.slaveId;
    if(secondary) { if(CDP==1) CDP=9; else if(CDP==9) CDP=1; }
    
    // Process data
    //    if(!cdp.status.isRaw && !cdp.status.isCompressed) Do(kCalibration);
    if(cdp.status.isRaw){

      // Prepare some nice histograms
      /*
      if(daq_histograms==0){
	daq_histograms=new TH1F*[RICmaxpmts*RICnwindows*2];   // pixels*gains*pmts
	for(int pmt=0;pmt<RICmaxpmts;pmt++)
	  for(int pixel=0;pixel<RICnwindows;pixel++)
	    for(int gain=0;gain<2;gain++){
	      char histo_name[1024];
	      sprintf(histo_name,"Rich_PMT_%i_pixel_%i_gain_%i",pmt,pixel,gain);
	      daq_histograms[gain+2*pixel+2*RICnwindows*pmt]=new TH1F(histo_name,histo_name,4096,-0.5,4095.5);
	    }
      }
      */

      if(cdp.length!=1+         // Status word
	 RICH_PMTperCDP*RICnwindows*2) Do(kCDPRawTruncated);

      // Fill raw information
      // Simple loop getting all the information

      DSPRawParser channel(cdp.data);

      do{
	//daq_histograms[channel.gain+2*channel.pixel+2*RICnwindows*channel.pmt]->Fill(channel.counts);

	// First comes the low gain, the high gain then
	if(channel.gain==0) {low_gain[channel.pmt][channel.pixel]=channel.counts;}
	else{
	  // Get the geom ID for this channel
	  int physical_cdp=Links[side][CDP];

	  if(physical_cdp!=-1){
	    int geom_id=RichPMTsManager::GetGeomPMTIdFromCDP(physical_cdp,channel.pmt);
	    if(geom_id>=0){
	      // Get the pixel geom id, substract the pedestal, check that
	      // it is above it and use low gain if necessary
	      int pixel_id=RichPMTsManager::GetGeomChannelID(geom_id,channel.pixel);
	      
	      if(RichPMTsManager::Status(geom_id,pixel_id)%10==Status_good_channel){  // Channel is OK
		int mode=1;                 // High gain
		int counts=channel.counts;
		
		if(channel.counts>RichPMTsManager::GainThreshold(geom_id,pixel_id)){
		  counts=low_gain[channel.pmt][channel.pixel];
		  mode=0;
		}

		float threshold=RichPMTsManager::PedestalThreshold(geom_id,pixel_id,mode)*
		  RichPMTsManager::PedestalSigma(geom_id,pixel_id,mode);
		
		// Add the hit
		int channel_geom_number=RichPMTsManager::PackGeom(geom_id,pixel_id);
		counts-=int(RichPMTsManager::Pedestal(geom_id,pixel_id,mode));
		
		if(!cdp.status.isCompressed)  	   // Just in case it is Mixed mode			
		  if(counts>threshold || mode==0)
		  AMSEvent::gethead()->
		    addnext(
			    AMSID("AMSRichRawEvent",0),
			    new AMSRichRawEvent(channel_geom_number,
						counts,
						mode?0:gain_mode)
			    );
	      }
	    }
	  }
	}
      }while(channel.Next());

    }
  
    if(cdp.status.isCompressed){
      //      if(cdp.status.isRaw)Do(kMixedMode); // Nothing to do indeed
      // Fill compressed mode if something to fill 
      if(cdp.length-1>0){
	DSPCompressedParser channel(cdp.data,cdp.length-1);
	
	do{
	  int physical_cdp=Links[side][CDP];
	  if(physical_cdp!=-1){
	    int geom_id=RichPMTsManager::GetGeomPMTIdFromCDP(physical_cdp,channel.pmt);
	    
//	    if(geom_id<0) Do(kWrongCDPChannelNumber);
	    if(geom_id<0) continue;    
	    // Get the pixel geom id, substract the pedestal, check that
	    // it is above it and use low gain if necessary
	    int pixel_id=RichPMTsManager::GetGeomChannelID(geom_id,channel.pixel);

	    if(RichPMTsManager::Status(geom_id,pixel_id)%10==Status_good_channel){  // Channel is OK
	      int mode=channel.gain;                 // High gain
	      int counts=channel.counts;

	      if(channel.inconsistent){
		// Substract the Gx1 pedestal
		counts-=int(RichPMTsManager::Pedestal(geom_id,pixel_id,0));
	      }

	      int channel_geom_number=RichPMTsManager::PackGeom(geom_id,pixel_id);

#ifdef __INSPECT__
	      cout<<"ADDING HIT IN COMPRESSED MODE: "<<endl
		  <<"   PMT GEOM ID "<<channel_geom_number<<endl
		  <<"   COUNTS  "<<counts<<endl
		  <<"   HIGH GAIN "<<mode<<endl;
#endif

	      AMSEvent::gethead()->addnext(AMSID("AMSRichRawEvent",0),
					   new AMSRichRawEvent(channel_geom_number,
							       counts,
							       mode?0:gain_mode));
	      
	    }
	  }
	}while(channel.Next());
	
      }
    }
    pointer=cdp.next;
  }

}
コード例 #3
0
ファイル: vars.c プロジェクト: ZRouter/ZRouter
void
AcceptCommand(int ac, char *av[], Options opt, ConfInfo list)
{
  Do(ACCEPT, ac, av, opt, list);
}
コード例 #4
0
ファイル: 14_set_b100w_bit_0.c プロジェクト: 0day-ci/gcc
int
main (void)
{
  Do ();
  return (*p == 0x1235) ? 0 : 1;
}
コード例 #5
0
ファイル: main.c プロジェクト: agdhun/Multifrt
int main(void)
{
	
//! [setup_init]
	system_init();

	//延时、串口初始化
	delay_init();
	configure_usart();
	configure_usart1();
	
	//配置输入输出变量
	port_get_config_defaults(&pini);
	port_get_config_defaults(&pinc);
	pinc.direction = PORT_PIN_DIR_OUTPUT;
	
	//延时20s,使MQ2、MQ7充分初始化
	delay_s(20);
	
	//MQ2、MQ7初始化输出模拟电压值
	mq2_init_value = mq_run(MQ2);
	mq7_init_value = mq_run(MQ7);
	
	//对ESP8266进行WIFI配置初始化
	esp_init();
//! [setup_init]

	//port_group_set_output_level(LED_0_PIN, LED_0_ACTIVE);
	
//! [main]
	//定义串口接收变量,用户端口号
	uint16_t temp='H', user = '******';
	
//! [main_loop]
	while (true) {
		if(usart_read_wait(&usart_instance, &temp) == STATUS_OK)
		{
			delay_us(8);
			if(temp == 'D')
			{
				while(usart_write_wait(&usart_inst1, 'T')!=STATUS_OK){}
				if(usart_read_wait(&usart_instance, &temp) == STATUS_OK)
				{
					
					if(temp == ',')
					{
						while(usart_write_wait(&usart_inst1, 'E')!=STATUS_OK){}
						if(usart_read_wait(&usart_instance, &temp) == STATUS_OK)
						{
							user = temp;
							while(usart_write_wait(&usart_inst1, 'S')!=STATUS_OK){}
							while(true)
							{
								if(usart_read_wait(&usart_instance, &temp) == STATUS_OK)
								{
									if(islower(temp))
									{
										while(usart_write_wait(&usart_inst1, 'T')!=STATUS_OK){}
										Do(temp, user);
										break;
									}
								}
							}
						}
					}
				}
			}
		}
	}
	//! [main]
}
コード例 #6
0
	typename std::enable_if<std::is_reference<U>::value, MethodStubbingProgress<R, arglist...>&>::type
	Return(const R& r) {
		return Do([&r](const arglist&...)->R {return r;});
	}
コード例 #7
0
ファイル: 05_b100b_to_var.c プロジェクト: 0day-ci/gcc
int
main (void)
{
  Do ();
  return (yData == 0x34) ? 0 : 1;
}
コード例 #8
0
ファイル: Parser.cpp プロジェクト: AbdelghaniDr/mirror
void Parser::Do()
{
	while(lex != t_eof && lex != '}') {
		Line();
		if(Key(tk_using)) {
			while(!Key(';'))
				++lex;
		}
		else
		if(Key(tk_extern) && lex == t_string) {
			++lex;
			++lex;
			if(Key('{')) {
				Do();
				Key('}');
			}
			Key(';');
		}
		else
		if(Key(tk_template)) {
			if(lex.IsId() || lex == tk_class && lex.IsId(1)) {
				Key(tk_class);
				for(;;) {
					if(lex.IsId())
						lex.GetId();
					else
					if(!Key(t_dblcolon))
						break;
				}
				TemplateParams();
				Key(';');
			}
			else {
				String tnames;
				String tparam = TemplateParams(tnames);
				if(!Nest(tparam, tnames)) {
					Array<Decl> r = Declaration(true, true);
					for(int i = 0; i < r.GetCount(); i++) {
						Decl& d = r[i];
						d.natural = "template" + tparam + ' ' + d.natural;
						if(context.access != PRIVATE && !d.isfriend && d.function) {
							CppItem& im = Item(context.nameing, context.nesting, d.natural);
							im.name = d.name;
							im.access = context.access;
							im.header = Purify(d.header);
							im.ender = Purify(d.ender);
							im.kind = context.nesting.IsEmpty() ? FUNCTIONTEMPLATE :
									  d.s_static ? CLASSFUNCTIONTEMPLATE
												 : INSTANCEFUNCTIONTEMPLATE;
							for(int i = 0; i < d.param.GetCount(); i++) {
								ScAdd(im.param, d.param[i].natural);
								ScAdd(im.pname, d.param[i].name);
							}
							im.tname = tnames;
							im.tparam = CleanTp(tparam);
						}
					}
					EatBody();
					Key(';');
				}
			}
		}
		else
		if(lex == tk_enum && (lex[1] == '{' || lex[2] == '{')) {
			++lex;
			String name;
			if(lex.IsId())
				name = lex.GetId();
			String param;
			String pname;
			String n = "enum " + name + " { ";
			Key('{');
			for(;;) {
				String val;
				Check(lex.IsId(), "Expected identifier");
				String nm = lex.GetId();
				if(Key('='))
					val = Constant();
				if(!param.IsEmpty())
					n << ", ";
				n << nm;
				ScAdd(param, nm + " = " + val);
				ScAdd(pname, nm);
				Key(',');
				if(Key('}')) break;
			}
			n << " }";
			CppItem& im = Item(context.nameing, context.nesting, n);
			im.kind = ENUM;
			im.name = name;
			im.access = context.access;
			im.param = param;
			im.pname = pname;
			if(lex.IsId())
				im.name = lex.GetId();
			CheckKey(';');
		}
		else
		if(Key('#')) {
			String n = lex.GetText();
			CppItem& im = Item(context.nameing, context.nesting, n);
			im.kind = MACRO;
			im.name.Clear();
			const char *s = n;
			while(*s && iscid(*s))
				im.name.Cat(*s++);
			s = strchr(n, '(');
			if(s) {
				s++;
				String p;
				for(;;) {
					if(iscid(*s))
						p.Cat(*s++);
					else {
						ScAdd(im.pname, p);
						p.Clear();
						if(*s == ')' || *s == '\0') break;
						s++;
					}
				}
			}
			im.access = context.access;
		}
		else
		if(!Nest(String(), String())) {
			if(Key(tk_public)) {
				context.access = PUBLIC;
				Key(':');
			}
			else
			if(Key(tk_private)) {
				context.access = PRIVATE;
				Key(':');
			}
			else
			if(Key(tk_protected)) {
				context.access = PROTECTED;
				Key(':');
			}
			else {
				const char *p = lex.Pos();
				Array<Decl> r = Declaration(true, true);
				bool body = EatBody();
				for(int i = 0; i < r.GetCount(); i++) {
					Decl& d = r[i];
					if(context.access != PRIVATE && !d.isfriend || d.isfriend && body) {
						CppItem& im = Item(context.nameing, context.nesting, d.natural);
						im.name = d.name;
						im.header = Purify(d.header);
						im.ender = Purify(d.ender);
						im.access = context.access;
						if(d.function) {
							im.kind = d.istructor ? (d.isdestructor ? DESTRUCTOR : CONSTRUCTOR) :
							          d.isfriend ? INLINEFRIEND :
							          context.nesting.IsEmpty() ? FUNCTION :
							          d.s_static ? CLASSFUNCTION : INSTANCEFUNCTION;
							for(int i = 0; i < d.param.GetCount(); i++) {
								ScAdd(im.param, d.param[i].natural);
								ScAdd(im.pname, d.param[i].name);
							}
						}
						else
							im.kind = d.type_def ? TYPEDEF :
							          context.nesting.IsEmpty() ? VARIABLE :
							          d.s_static ? CLASSVARIABLE : INSTANCEVARIABLE;
					}
				}
				EatBody();
				Key(';');
			}
		}
	}
}
コード例 #9
0
ファイル: vars.c プロジェクト: ZRouter/ZRouter
void
EnableCommand(int ac, char *av[], Options opt, ConfInfo list)
{
  Do(ENABLE, ac, av, opt, list);
}
コード例 #10
0
ファイル: vars.c プロジェクト: ZRouter/ZRouter
void
DisableCommand(int ac, char *av[], Options opt, ConfInfo list)
{
  Do(DISABLE, ac, av, opt, list);
}
コード例 #11
0
ファイル: vars.c プロジェクト: ZRouter/ZRouter
void
YesCommand(int ac, char *av[], Options opt, ConfInfo list)
{
  Do(ENABLE, ac, av, opt, list);
  Do(ACCEPT | NO_SCOLD, ac, av, opt, list);
}
コード例 #12
0
ファイル: vars.c プロジェクト: ZRouter/ZRouter
void
NoCommand(int ac, char *av[], Options opt, ConfInfo list)
{
  Do(DISABLE, ac, av, opt, list);
  Do(DENY | NO_SCOLD, ac, av, opt, list);
}
コード例 #13
0
ファイル: vars.c プロジェクト: ZRouter/ZRouter
void
DenyCommand(int ac, char *av[], Options opt, ConfInfo list)
{
  Do(DENY, ac, av, opt, list);
}
コード例 #14
0
ファイル: richdaq.C プロジェクト: krafczyk/AMS
void DAQRichBlock::buildraw(integer length,int16u *p){
  // The length integer includes the jinj id information in the hsb
  unsigned int jinj=length>>24;
  length&=(1<<24)-1;

  try{
  // Reset the status bits
  Status=kOk;
#ifdef __INSPECT__
  cout<<endl<<endl<<"RICH EVENT INSPECTOR: buildraw"<<endl;
  cout<<endl;
  cout<< " -1(-2) -- LENGTH                   -- "<<length<<" words"<<endl;
  int16u value=*p;
  printf("0       -- 1 0 nodeaddress datatype -- %i %i %i %x\n ",
	 (value&(1<<15))>>15,
	 (value&(1<<14))>>14,
	 (value&(0b0011111111100000))>>5,
	 (value&(0b11111)));

  printf("MASK    -- mask %x \n",*(p-2+length));
  printf("???     -- status %x\n",*(p-1+length));
  StatusParser parsed(*(p-1+length));
  printf("        --  SlaveId %i IsCDP %i is RAW %i isCompressed %i isData %i\n",
	 parsed.slaveId,
	 parsed.isCDP,
	 parsed.isRaw,
	 parsed.isCompressed,
	 parsed.isData);
  cout<<endl<<endl;

  cout<<"DUMPING EVERYTHING "<<endl;
  for(int i=0;i<length;i++) {cout<<"+"<<i<<" ";printf("%x\n",*(p+i));}
#endif

  // Check that the length size is the correct one: at least I expect to have the node status
  if(length<1) Do(kLengthError);
  
  // This is supposed to be a JINF block: get the status word and check it
  StatusParser status(*(p-1+length));
  // if(!status.isData || status.errors || status.isCDP) Do(kDataError);
  if(status.errors || status.isCDP) Do(kDataError);
  
  // Get the JINF number
  uint id=status.slaveId;  
  int JINF=-1;
  for(int i=0;i<RICH_JINFs;i++) if(JINFId[i]==int(id)) {JINF=i;break;}
  if(JINF==-1) Do(kJINFIdError);
  

  // Assume that everything here is primary and decode
  int offset=0;
  if(DAQCFFKEY.DAQVersion==1) offset=-2;  // Take into account the JINF-R MASK
  if(!AMSJob::gethead()->isRealData()) offset=-2;  // Take into account the added JINF-R MASK for MC data

  bool secondary=0;
  if(AMSJob::gethead()->isRealData()) if(jinj==0 || jinj==3) secondary=1;
  DecodeRich(length+offset,p,JINF,secondary);
  }
  catch(int){
    static bool first_call=true;
    if(first_call){
      cout<<"-- Problem in DAQRichBlock::buildraw. Ignoring further errors"<<endl;
      first_call=false;
    }
  }
}
コード例 #15
0
ファイル: HTCPClient.cpp プロジェクト: pigbrain/HNet
void HTCPClient::Run()
{
	while (false == m_bDestroy)
		Do();
}
コード例 #16
0
ファイル: Parser.cpp プロジェクト: AbdelghaniDr/mirror
bool Parser::Nest(const String& tp, const String& tn) {
	if(Key(tk_namespace)) {
		Check(lex.IsId(), "Expected name of namespace");
		String name = lex.GetId();
		if(Key('{')) {
			Context cc;
			cc <<= context;
			context.nameing << name << "::";
			Do();
			context <<= cc;
			Key('}');
		}
		Key(';');
		return true;
	}
	if((lex == tk_class || lex == tk_struct || lex == tk_union) &&
	   lex.IsId(1) &&
	   (lex[2] == ':' || lex[2] == ';' || lex[2] == '{')) {
		int t = lex.GetCode();
		context.typenames.FindAdd(lex);
		String name = lex.GetId();
		Context cc;
		cc <<= context;
		if(context.nesting.IsEmpty())
			context.nesting = name + TrimRight(tp);
		else
			context.nesting = context.nesting + "::" + name + TrimRight(tp);
		context.access = t == tk_class ? PRIVATE : PUBLIC;
		String nn;
		if(!tp.IsEmpty())
			nn = "template " + tp + " ";
		nn << (t == tk_class ? "class " : t == tk_union ? "union " : "struct ") + name;
		CppItem& im = Item(context.nameing, context.nesting, nn);
		im.kind = tp.IsEmpty() ? STRUCT : STRUCTTEMPLATE;
		im.name = name;
		im.access = cc.access;
		im.tname = tn;
		im.tparam = CleanTp(tp);
		if(Key(':')) {
			do {
				String access = t == tk_class ? "private" : "public";
				if(Key(tk_public)) access = "public";
				else
				if(Key(tk_protected)) access = "protected";
				else
				if(Key(tk_private)) access = "private";
				if(Key(tk_virtual)) access << " virtual";
				String n = Name();
				ScAdd(im.pname, n);
				ScAdd(im.param, access + ' ' + n);
			}
			while(Key(','));
		}
		if(Key('{')) {
			Do();
			CheckKey('}');
		}
		CheckKey(';');
		context = cc;
		return true;
	}
	return false;
}
コード例 #17
0
ファイル: 27_if0_b100w_bitfield_8.c プロジェクト: 0day-ci/gcc
int
main (void)
{
  return Do ()[0] == 'F';
}
コード例 #18
0
void Win32Window::Run(ptr<Handler> activeHandler)
{
	while(Do(activeHandler));
}
コード例 #19
0
ファイル: DiffSyntax.cpp プロジェクト: ultimatepp/mirror
void DiffSyntax::Highlight(const wchar *start, const wchar *end, HighlightOutput& hls, CodeEditor *editor, int line, int pos)
{
	hout = &hls;
	Do(start, end, editor, line, editor ? editor->GetTabSize() : 4, pos);
	hout = NULL;
}
コード例 #20
0
	MethodStubbingProgress<R, arglist...>&
	Do(const first& f, const second& s, const tail&... t) {
		Do(f);
		return Do(s, t...);
	}
コード例 #21
0
ファイル: 15_clr_b100w_bit_7.c プロジェクト: 0day-ci/gcc
int
main (void)
{
  Do ();
  return (*p == 0xed4b) ? 0 : 1;
}
コード例 #22
0
	MethodStubbingProgress<R, arglist...>&
	Return() {
		return Do([](const arglist&...)->R {return DefaultValue<R>::value();});
	}
コード例 #23
0
ファイル: doc.cpp プロジェクト: EdgarTx/wx
bool csCommandState::Undo()
{
  switch (m_cmd)
  {
    case ID_CS_CUT:
    {
        wxASSERT( (m_savedState != NULL) );
        wxASSERT( (m_doc != NULL) );

        m_doc->GetDiagram()->AddShape(m_savedState);
        m_shapeOnCanvas = m_savedState;
        m_savedState = NULL;

        if (m_shapeOnCanvas->IsKindOf(CLASSINFO(wxLineShape)))
        {
            wxLineShape* lineShape = (wxLineShape*) m_shapeOnCanvas;
            lineShape->GetFrom()->AddLine(lineShape, lineShape->GetTo(),
                lineShape->GetAttachmentFrom(), lineShape->GetAttachmentTo(),
                m_linePositionFrom, m_linePositionTo);

            wxShapeCanvas* canvas = lineShape->GetFrom()->GetCanvas();

            wxClientDC dc(canvas);
            canvas->PrepareDC(dc);

            lineShape->GetFrom()->MoveLinks(dc);
            lineShape->GetTo()->MoveLinks(dc);

        }
        m_shapeOnCanvas->Show(true);

        m_doc->Modify(true);
        m_doc->UpdateAllViews();
        break;
    }
    case ID_CS_ADD_SHAPE:
    case ID_CS_ADD_LINE:
    case ID_CS_ADD_SHAPE_SELECT:
    case ID_CS_ADD_LINE_SELECT:
    {
        wxASSERT( (m_shapeOnCanvas != NULL) );
        wxASSERT( (m_savedState == NULL) );
        wxASSERT( (m_doc != NULL) );

        // In case this is a line
        wxShape* lineFrom = NULL;
        wxShape* lineTo = NULL;
        int attachmentFrom = 0, attachmentTo = 0;

        if (m_shapeOnCanvas->IsKindOf(CLASSINFO(wxLineShape)))
        {
            // Store the from/to info to save in the line shape
            wxLineShape* lineShape = (wxLineShape*) m_shapeOnCanvas;
            lineFrom = lineShape->GetFrom();
            lineTo = lineShape->GetTo();
            attachmentFrom = lineShape->GetAttachmentFrom();
            attachmentTo = lineShape->GetAttachmentTo();
        }

        wxClientDC dc(m_shapeOnCanvas->GetCanvas());
        m_shapeOnCanvas->GetCanvas()->PrepareDC(dc);

        m_shapeOnCanvas->Select(false, &dc);
        ((csDiagramView*) m_doc->GetFirstView())->SelectShape(m_shapeOnCanvas, false);
        m_doc->GetDiagram()->RemoveShape(m_shapeOnCanvas);
        m_shapeOnCanvas->Unlink(); // Unlinks the line, if it is a line

        if (m_shapeOnCanvas->IsKindOf(CLASSINFO(wxLineShape)))
        {
            // Restore the from/to info for future reference
            wxLineShape* lineShape = (wxLineShape*) m_shapeOnCanvas;
            lineShape->SetFrom(lineFrom);
            lineShape->SetTo(lineTo);
            lineShape->SetAttachments(attachmentFrom, attachmentTo);
        }

        m_savedState = m_shapeOnCanvas;
        m_shapeOnCanvas = NULL;

        m_doc->Modify(true);
        m_doc->UpdateAllViews();
        break;
    }
    case ID_CS_CHANGE_BACKGROUND_COLOUR:
    case ID_CS_MOVE:
    case ID_CS_SIZE:
    case ID_CS_EDIT_PROPERTIES:
    case ID_CS_FONT_CHANGE:
    case ID_CS_ARROW_CHANGE:
    case ID_CS_ROTATE_CLOCKWISE:
    case ID_CS_ROTATE_ANTICLOCKWISE:
    case ID_CS_CHANGE_LINE_ORDERING:
    case ID_CS_CHANGE_LINE_ATTACHMENT:
    case ID_CS_ALIGN:
    case ID_CS_NEW_POINT:
    case ID_CS_CUT_POINT:
    case ID_CS_MOVE_LINE_POINT:
    case ID_CS_STRAIGHTEN:
    case ID_CS_MOVE_LABEL:
    {
        // Exactly like the Do case; we're just swapping states.
        Do();
        break;
    }
  }

    return true;
}