[ANSI C] strtoq implementation for C89...

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • unauthorized
    New Member
    • May 2009
    • 81

    [ANSI C] strtoq implementation for C89...

    Hi guys. I've been trying to compile the pcre library for use with the MSVC compiler, but the code wouldn't compile because it needed the func strtoq which isn't part of my C(++) library.
    Anyway, I figured I may as well get down and dirty with it and write a quick replacement (and it worked fine) but once I tried compiling it as a .c source, bad things happened:

    Compiler log:
    Code:
    ------ Build started: Project: pcre, Configuration: Debug Win32 ------
    Compiling...
    msvc_fix.c
    ..\msvc_fix.c(11) : error C2143: syntax error : missing ';' before 'type'
    ..\msvc_fix.c(14) : error C2065: 'is_negative' : undeclared identifier
    ..\msvc_fix.c(17) : error C2065: 'is_negative' : undeclared identifier
    ..\msvc_fix.c(19) : error C2143: syntax error : missing ';' before 'type'
    ..\msvc_fix.c(20) : error C2143: syntax error : missing ';' before 'type'
    ..\msvc_fix.c(22) : error C2143: syntax error : missing ';' before 'const'
    ..\msvc_fix.c(24) : error C2065: 'p' : undeclared identifier
    ..\msvc_fix.c(24) : error C2100: illegal indirection
    ..\msvc_fix.c(26) : error C2065: 'p' : undeclared identifier
    ..\msvc_fix.c(29) : error C2065: 'p' : undeclared identifier
    ..\msvc_fix.c(31) : error C2065: 'p' : undeclared identifier
    ..\msvc_fix.c(31) : warning C4047: '>' : 'int' differs in levels of indirection from 'const char *'
    ..\msvc_fix.c(33) : error C2065: 'p' : undeclared identifier
    ..\msvc_fix.c(34) : error C2143: syntax error : missing ';' before 'type'
    ..\msvc_fix.c(35) : error C2065: 'this_val' : undeclared identifier
    ..\msvc_fix.c(35) : error C2065: 'this_val' : undeclared identifier
    ..\msvc_fix.c(37) : error C2065: 'is_negative' : undeclared identifier
    ..\msvc_fix.c(38) : error C2065: 'result' : undeclared identifier
    ..\msvc_fix.c(38) : error C2065: 'base_mul' : undeclared identifier
    ..\msvc_fix.c(38) : error C2065: 'this_val' : undeclared identifier
    ..\msvc_fix.c(39) : error C2065: 'result' : undeclared identifier
    ..\msvc_fix.c(40) : error C2065: 'result' : undeclared identifier
    ..\msvc_fix.c(44) : error C2065: 'result' : undeclared identifier
    ..\msvc_fix.c(44) : error C2065: 'base_mul' : undeclared identifier
    ..\msvc_fix.c(44) : error C2065: 'this_val' : undeclared identifier
    ..\msvc_fix.c(45) : error C2065: 'result' : undeclared identifier
    ..\msvc_fix.c(46) : error C2065: 'result' : undeclared identifier
    ..\msvc_fix.c(51) : error C2065: 'base_mul' : undeclared identifier
    ..\msvc_fix.c(54) : error C2065: 'result' : undeclared identifier
    Build log was saved at "file://d:\lib\pcre-7.9\build\pcre.dir\Debug\BuildLog.htm"
    pcre - 28 error(s), 1 warning(s)
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    Source code:
    Code:
    #ifndef _MSC_VER
    #error This source file is for use with Microsoft Visual Studio only.
    #error Please remove it from your makefile/project and try again.
    #endif /* _MSC_VER */
    
    long long strtoq(const char* nptr, char** endptr, int base)
    {
    	if(base < 0 || base > 36) return 0;
    	if(nptr == 0) return 0;
    
    	int is_negative;
    
    	if(nptr[0] == '-') {
    		is_negative = 1;
    		nptr++;
    	} else {
    		is_negative = 0;
    	}
    	long long result = 0;
    	long long base_mul = 1;
    
    	const char* p = nptr;
    	while(1) {
    		char this_val = *p - '0';
    		if(this_val < 0 || this_val > 9) break;
    		else p++;
    	}
    
    	if(endptr) *endptr = (char*)(p); // note: const cast
    
    	while(p > nptr)
    	{
    		p--;
    		char this_val = *p - '0';
    		if(this_val < 0 || this_val > 9) break;
    
    		if(is_negative) {
    			result -= base_mul * this_val;
    			if(result > 0) { // overflow!
    				result = 0;
    				break;
    			}
    		} else {
    			result += base_mul * this_val;
    			if(result < 0) { // underflow!
    				result = 0;
    				break;
    			}
    		}
    
    		base_mul *= base;
    	}
    
    	return result;
    }
    Now I'm not a C guru, but I've done some ANSI C coding before and I don't see why this wouldn't compile. Initially I thought that VC being (mostly) C89 compliant doesn't recognize "long long" but that turned out not to be the case. Any ideas why the compiler expects ";" before "int"?
  • newb16
    Contributor
    • Jul 2008
    • 687

    #2
    I googled for 'c89 variable declaration' and found this -
    For C89, you must declare all of your variables at the beginning of a scope block. is_negative seems to violate it.

    Comment

    • unauthorized
      New Member
      • May 2009
      • 81

      #3
      Originally posted by newb16
      I googled for 'c89 variable declaration' and found this -
      For C89, you must declare all of your variables at the beginning of a scope block. is_negative seems to violate it.
      Well that explains why gcc wasn't complaining. Thanks, man.

      Comment

      Working...