Home AMXForums Archive Threads AMX Applications and Solutions

Sinteger to Integer & odd error?

In the below code block I been writing as part a module (include file) for reading and writing to the CF card, basically the C:\ drive. Off subject slightly but on the CF you normally read and write to the "user" directory (C:\user) which is the directory you FTP into. Through file_dir commands you can go up a directory using /../ to the main "C:\" directory where the program folders and files live. Question; how to access this through FTP? I can open and display the contents on the TP through code but that's about it. I don't want to do anything with files other than examine them but requires alot more code and conversion to do on a TP. I'm just curious as to how I can view these from FTP.

Back on subject; In the code block I was having Sinteger to Integer warnings which were bugging me so I wrote the function on top to convert. Question, was I missing something simple/stupid I could have done to avoid this and eliminate the warnings or maybe do something differnent other than using this function?

2nd question; towards the bottom of the code block there is a line commented out in the switch case which creates this when compiling if not commented out:

Starting NetLinx Compile - Version[2.3.0.0] [08-31-2006 18:29:53]
C:\Documents and Settings\DVining\Desktop\DansDESKTOP\AMX\AMX_Programming\VAV_Office_Programs\VAV_Office_System.axs
ERROR: (0): C10580: Internal Error: Major system error occurred during code generation
C:\Documents and Settings\DVining\Desktop\DansDESKTOP\AMX\AMX_Programming\VAV_Office_Programs\VAV_Office_System.axs - 1 error(s), 0 warning(s)
NetLinx Compile Complete [08-31-2006 18:29:58]

I'm switching a Slong data type which matkes the thread title wrong as that's the same VAR but that's irrelevant. Any ideas as to why with this line uncommented I would get this compiler error with no line number reference or desciption. It had me baffled for an hour or more because I'm so burnt I didn't remember that I had just recently added that line before this compiler error started. Which is a problem when you do ten things and then try to compile, oh yeah and burnt.

It's just a F_in zero!
DEFINE_FUNCTION INTEGER fnConvertSINT_to_INT(CHAR iSinteger[]) 
     {
     stack_var char cWaste [1] ;
     local_var char cTempNumber [6] ;
     
     cTempNumber = iSInteger ;
     if (find_string(cTempNumber,'+',1) || find_string(cTempNumber,'-',1))
	  {
	  cWaste = get_buffer_char(cTempNumber) ;
	  }
     RETURN atoi(cTempNumber) ;
     }
     
DEFINE_FUNCTION CHAR fnFileDirectory(CHAR icFileDirPath[],CHAR iDoWhat [])
     {
     stack_var long nFileDirEntry ;
     local_var slong nFDirReturn ;
     local_var integer nConvert ;
     stack_var char cFileDirBuf [MaxFileDirBufLength] ;
          
     nFileDirEntry = 1 ;
     nFDirReturn = file_dir(icFileDirPath,cFileDirBuf,nFileDirEntry + nFEntryOffset) ;
     if (nFDirReturn > 0)
	  {
	  nConvert = fnConvertSINT_to_INT(itoa(nFDirReturn)) ;
	  nFnumFilesInDir = nFEntryOffset + (nConvert + 1) ;
	  if(iDoWhat != 'PageUpBtn'  &&  iDoWhat != 'PageDwnBtn')
	       {
	       fnFResetPageNum() ;
	       }
	  SEND_STRING 0,"'FUNCTION fnFileDirectory. File_Dir inquiry returned successful! ',itoa(nConvert +1),
						       ' files/folders found! line-<',ITOA(__LINE__),'>',crlf" ;
						       
	  fnClearDispFileList('NORMAL','FileDir')
	  while(nFDirReturn > 0 && nFileDirEntry <= MaxDisplayFileList) 
	       {
	       nFDirReturn = file_dir(icFileDirPath,cFileDirBuf,nFileDirEntry + nFEntryOffset) ;
	       if (length_string(cFileDirBuf)) 
		    {
		    stack_var integer nFileDirForF
		    nFileDirForF = find_string(cFileDirBuf,'/',1) ;
		    if(nFileDirForF == 1)
			 {
			 sFFList[nFileDirEntry].FileFolder = mid_string(cFileDirBuf,2,length_string(cFileDirBuf)-1) ;
			 sFFList[nFileDirEntry].FFicon = 'folder' ;
			 }
		    else
			 {
			 sFFList[nFileDirEntry].FileFolder = cFileDirBuf ;
			 sFFList[nFileDirEntry].FFicon = 'file' ;
			 }
		    nFileDirEntry ++ ;
		    }
	       }
	   SEND_STRING 0,"'FUNCTION fnFileDirectory. File_Dir returned. Return = ',itoa(nFileDirEntry -1),
						       ' + offset ',ITOA(nFEntryOffset),' Line-<',ITOA(__LINE__),'>',crlf" ;
	  fnFLoadStructures('FileDir') ;
	  }
     else
	  {
	  stack_var char cErrorMsg [100] ;
	  switch (itoa(nFDirReturn)) 
	       {
	      // case '0'  : {cErrorMsg = 'directory empty or unkown directory error'} ;
	       case '-4' : {cErrorMsg = 'invalid directory path'} ;
	       case '-10': {cErrorMsg = 'buffer too small'} ;
	       case '-6' : {cErrorMsg = 'invalid parameter (i.e. Entry points beyond the end of the directory)'} ;
	       case '-12': {cErrorMsg = 'directory not loaded'} ;
	       case '-5' : {cErrorMsg = 'Disk I/O error'} ;
	       }
	  nFnumFilesInDir = nFEntryOffset + 0 ;
	  sFFList[1].FileFolder = cErrorMsg ;
	  sFFList[1].FFicon = 'file' ;
	  fnClearDispFileList('ERROR','FileDir') ;
	  SEND_STRING 0,"'FUNCTION fnFileDirectory. Bad File_Directory return: ',cErrorMsg,'! line-<',ITOA(__LINE__),'>',crlf" ;
	  }
     RETURN TRUE ;
     }

Comments

  • NMarkRobertsNMarkRoberts Junior Member Posts: 455
    Major system error

    It looks like another example of NS2's difficulty in typecasting single character strings.

    The error only occurs when the first case is a single character - it doesn't matter what the character is - and it's OK if the single character appears later in the sequence, or all of the rest of the cases are single characters too.
  • NMarkRobertsNMarkRoberts Junior Member Posts: 455
    Converting sinteger to integer

    The type_cast comand appears to do the job OK.
  • viningvining X Member Posts: 4,358
    Well the type_cast was the simple answer I couldn't find and never used before but is exactly what I wanted.

    The switch_case thing is just bizarre and I know it's going to come back soemtime in the future and bite me in the A$$ again. Unless I remember, yeah right.

    I haven't run the code and debugged but it does compile and hopefully it works!

    Revised code showing the modifications:
    DEFINE_FUNCTION CHAR fnFileDirectory(CHAR icFileDirPath[],CHAR iDoWhat [])
         {
         stack_var long nFileDirEntry ;
         local_var slong nFDirReturn ;
         local_var integer nConvert ;
         stack_var char cFileDirBuf [MaxFileDirBufLength] ;
              
         nFileDirEntry = 1 ;
         nFDirReturn = file_dir(icFileDirPath,cFileDirBuf,nFileDirEntry + nFEntryOffset) ;
         if (nFDirReturn > 0)
    	  {
    	  nConvert = type_cast(nFDirReturn) ;
    	  nFnumFilesInDir = nFEntryOffset + (nConvert + 1) ;
    	  if(iDoWhat != 'PageUpBtn'  &&  iDoWhat != 'PageDwnBtn')
    	       {
    	       fnFResetPageNum() ;
    	       }
    	  SEND_STRING 0,"'FUNCTION fnFileDirectory. File_Dir inquiry returned successful! ',itoa(nConvert +1),
    						       ' files/folders found! line-<',ITOA(__LINE__),'>',crlf" ;
    						       
    	  fnClearDispFileList('NORMAL','FileDir')
    	  while(nFDirReturn > 0 && nFileDirEntry <= MaxDisplayFileList) 
    	       {
    	       nFDirReturn = file_dir(icFileDirPath,cFileDirBuf,nFileDirEntry + nFEntryOffset) ;
    	       if (length_string(cFileDirBuf)) 
    		    {
    		    stack_var integer nFileDirForF
    		    nFileDirForF = find_string(cFileDirBuf,'/',1) ;
    		    if(nFileDirForF == 1)
    			 {
    			 sFFList[nFileDirEntry].FileFolder = mid_string(cFileDirBuf,2,length_string(cFileDirBuf)-1) ;
    			 sFFList[nFileDirEntry].FFicon = 'folder' ;
    			 }
    		    else
    			 {
    			 sFFList[nFileDirEntry].FileFolder = cFileDirBuf ;
    			 sFFList[nFileDirEntry].FFicon = 'file' ;
    			 }
    		    nFileDirEntry ++ ;
    		    }
    	       }
    	  //nFnumFilesInDir = nFEntryOffset + (nFileDirEntry - 1) ;
    	  SEND_STRING 0,"'FUNCTION fnFileDirectory. File_Dir returned. Return = ',itoa(nFileDirEntry -1),
    						       ' + offset ',ITOA(nFEntryOffset),' Line-<',ITOA(__LINE__),'>',crlf" ;
    	  fnFLoadStructures('FileDir') ;
    	  }
         else
    	  {
    	  stack_var char cErrorMsg [100] ;
    	  switch (itoa(nFDirReturn)) 
    	       {
    	       case '-4' : {cErrorMsg = 'invalid directory path'} ;
    	       case '-10': {cErrorMsg = 'buffer too small'} ;
    	       case '-6' : {cErrorMsg = 'invalid parameter (i.e. Entry points beyond the end of the directory)'} ;
    	       case '-12': {cErrorMsg = 'directory not loaded'} ;
    	       case '-5' : {cErrorMsg = 'Disk I/O error'} ;
    	       case '0'  : {cErrorMsg = 'directory empty or unkown directory error'} ;
    	       }
    	  nFnumFilesInDir = nFEntryOffset + 0 ;
    	  sFFList[1].FileFolder = cErrorMsg ;
    	  sFFList[1].FFicon = 'file' ;
    	  fnClearDispFileList('ERROR','FileDir') ;
    	  SEND_STRING 0,"'FUNCTION fnFileDirectory. Bad File_Directory return: ',cErrorMsg,'! line-<',ITOA(__LINE__),'>',crlf" ;
    	  }
         RETURN TRUE ;
         }
    


    Anyone got an answer on the FTP thing!

    Much thanks

    Dan
  • DHawthorneDHawthorne Junior Member Posts: 4,584
    TYPE_CAST () just forces a data type change, it does no conversions, it can potemtially lose data. You have to be careful with it. For example, if you TYPE_CAST an integer value to a CHAR, it will be fine if the integer value is under 255. Any number higher, and the high order bits are just lost, changing the nummber entirely. So you can only safely use it when you know full well the target data type will hold your variable without loss. It's always safe, on the other hand, to TYPE_CAST up - like from CHAR to INTEGER.

    I would suspect your SINTEGER warning is being triggered by one of your arithmetic operations. If you add (or whatever) different data types, the compiler tries to convert them to like data types first, but sometimes the algorithm it uses to do this fails. Your error is coming from the compiler trying to convert data to a form it can't manage without potential data loss. Signed data types seem to have this trouble the most. Without pouring through the code, I would say you are trying to add an INTEGER to an SINTEGER (or perhaps an SLONG - it started a conversion and one of the intermediate conversions hung it up). TYPE_CAST or convert all your operands to the same data type and it won't fail. This is also safer in that you can choose the conversion to make, not leaving it up to the compiler and its precedence rules, which may not be exactly right for your situation.

    As for your SWITCH block - try putting the CASE 0 after the negative numbers. SWITCH seems to behave better if the CASEs are in order. If that doesn't fly, just conver the whole thing to a SELECT-ACTIVE block. They are much more versatile (if not as elegant). I often feel like we are missing a good deal of info about exactly how SWITCH-CASE works, and what it will accept and what it won't.
  • viningvining X Member Posts: 4,358
    The problem was indeed the math when adding a sinteger to integer or slong to long. It was behind a "if ( var > 0 )" condition so I knew it wasn't a negative number. That would likely be the only time I would need this so in this instance there's no chance of data loss.

    With the switch_case, I believe that was the order descibe in the
    File_Dir keyword help file and the zero I added because ocasionally I get a return of zero so it was more for my information than anything else that it was added, much to my dismay.

    In regard to the switch_case order I usually would put the most likely case first so it exits quicker and doesn't waiste time making needless comparisons. Not that my code is all that effecient but this I thought was a simple approach to expidite it. Now if there was some document that said it's better to arrange the case in a logical order I would, and obviously there's a numeric logical order to literal strings as well but as you stated, we don't know how they work and what if any thing would help them work more efficiently. I would love to know!
  • DHawthorneDHawthorne Junior Member Posts: 4,584
    vining wrote:
    In regard to the switch_case order I usually would put the most likely case first so it exits quicker and doesn't waiste time making needless comparisons. Not that my code is all that effecient but this I thought was a simple approach to expidite it. Now if there was some document that said it's better to arrange the case in a logical order I would, and obviously there's a numeric logical order to literal strings as well but as you stated, we don't know how they work and what if any thing would help them work more efficiently. I would love to know!
    That's exactly the problem; the issues with SWITCH/CASE are not documented at all. We have been piecing them together on these forums as we discover things that don't work. The problem with that approach is that sometimes we will detect a pattern, and it turns out that something else was the problem, and our analysis only really applied to the case we observed (in other words, it only looked like we found the answer). I just recall someone stating they had problems with it when the CASE statements were out of order. Since then, I have always arranged them that way myself, just to be safe. I wonder if the real issue is using them with signed values though. There may be another hidden type cast going on here.
  • kennyannkennyann Junior Member Posts: 113
    I have noticed that the switch/case does not work in the wait_until statement. I was using the wait_until for the my projector to turn on before sending the input command.
  • mpullinmpullin Obvious Troll Account, Marked for Deletion Posts: 949
    kennyann wrote:
    I have noticed that the switch/case does not work in the wait_until statement. I was using the wait_until for the my projector to turn on before sending the input command.

    Last I checked, switch/case couldn't be used within any type of wait.
  • NMarkRobertsNMarkRoberts Junior Member Posts: 455
    The help for both wait and switch does not state that the one may not be used inside the other, nor from my understanding of how they work can I imagine why that might be the case.
  • DHawthorneDHawthorne Junior Member Posts: 4,584
    I think it may use the stack memory for the CASE statements, and you can't use the stack inside a WAIT. This is one of the things that make me say the documentation is not as complete as it needs to be.
  • NMarkRobertsNMarkRoberts Junior Member Posts: 455
    I just compiled and loaded this code and it works fine, using a switch inside a wait:

    program_name = 'Fred'

    define_variable

    integer a = 1

    define_program

    wait 20
    {
    switch (a)
    {
    case 1:
    {
    send_string 0,'hello world'
    }
    }
    }
  • viningvining X Member Posts: 4,358
    That probably depends on the variable used in the case. Stacked, local or global. A local or global Switch(var) should work but obviously a stacked can't.
Sign In or Register to comment.