/************************************************************************** ** ** common.c - supporting function (just needed for prototyping application) ** *************************************************************************** */ #define EXTERN extern /*-------------------------- ** include files **-------------------------- */ #include #include #include #include #include #include "common.h" /*-------------------------- ** defines **-------------------------- */ #ifndef PASS #define PASS 0 #define FAIL -1 #endif #ifndef INRANGE #define INRANGE(a,x,b) ((a) <= (x) && (x) <= (b)) #endif /************************************************************************/ /* tony's junk */ /************************************************************************/ /*--------------------------------------------------------- ** strxcpy() - similar to strncpy, but will always ** place an null character at the end of dest. **--------------------------------------------------------- */ char * strxcpy ( char * dest, const char * src, int maxlen ) { strncpy( dest, src, maxlen ); dest[maxlen-1] = '\0'; return dest; } /*--------------------------------------------------------- ** str_rws() - changes white space characters in a string to ' '. **--------------------------------------------------------- */ char *str_rws( char * s, unsigned int maxlen ) { char *cptr = s; while( maxlen && *cptr!=0 ) { if( isspace( (int)*cptr ) ) *cptr = ' '; maxlen--; cptr++; } return s; } /*---------------------------------------------------------- ** unpad( s ) - removes beginning and trailing characters c ** from string s. Return s. **---------------------------------------------------------- */ char *unpad ( char * s, // string to modify. int c // unpads this character ) { int i, l; if( s==NULL) return(NULL); i = l = strlen(s); i--; while ( (i>=0) && (s[i]==c) ) s[i--] = 0; for( i=0; s[i]==c; i++); if( i > 0 ) memmove(s, s+i, l-i+1); return(s); } /*---------------------------------------------------------- ** parseInt_r() - parse & convert to int. **---------------------------------------------------------- */ int parseInt_r( int * ip, char *buf, const char *tok, char **st_ptr ) { char * c; long l; if( (c = strtok_r( buf, tok, st_ptr) ) == NULL) return FAIL; if( -1 == my_atol( c, &l)) return FAIL; *ip = (int)l; return PASS; } /*---------------------------------------------------------------- ** parseIntR_r() - parse & convert to int, with range checking **--------------------------------------------------------------- */ int parseIntR_r( int * ip, char *buf, const char *tok, char **st_ptr, int min, int max ) { int rc; if( (rc = parseInt_r( ip, buf, tok, st_ptr )) != PASS ) return rc; if( !INRANGE( min, *ip, max )) return FAIL; return PASS; } /*---------------------------------------------------------- ** parseLong_r() - parse & convert to long. **---------------------------------------------------------- */ int parseLong_r( long * lp, char *buf, const char *tok, char **st_ptr ) { char * c; long l; if( (c = strtok_r( buf, tok, st_ptr) ) == NULL) return FAIL; if( -1 == my_atol( c, &l)) return FAIL; *lp = l; return PASS; } /*---------------------------------------------------------------- ** parseLongR_r() - parse & convert to long, with range checking **--------------------------------------------------------------- */ int parseLongR_r( long * lp, char *buf, const char *tok, char **st_ptr, long min, long max ) { int rc; if( (rc = parseLong_r( lp, buf, tok, st_ptr )) != PASS ) return rc; if( !INRANGE( min, *lp, max )) return FAIL; return PASS; } /*---------------------------------------------------------- ** parseDouble_r() - parse & convert to double. **---------------------------------------------------------- */ int parseDouble_r( double *dp, char *buf, const char *tok, char **st_ptr ) { char * c; double d; if( (c = strtok_r( buf, tok, st_ptr) ) == NULL) return FAIL; d = atof( c ); *dp = d; return PASS; } /*-------------------------------------------------------------------- ** parseDoubleR_r() - parse & convert to double, with range checking **-------------------------------------------------------------------- */ int parseDoubleR_r( double *dp, char *buf, const char *tok, char **st_ptr, double min, double max ) { int rc; if( (rc = parseDouble_r( dp, buf, tok, st_ptr )) != PASS ) return rc; if( !INRANGE( min, *dp, max )) return FAIL; return PASS; } /*-------------------------------------------------------------------- ** parseString() - parse & copies a string into buf. **-------------------------------------------------------------------- */ int parseString_r( char *outb, int outb_size, char *buf, const char *tok, char ** st_ptr ) { char *c; if( (c = strtok_r( buf, tok, st_ptr) ) == NULL) return FAIL; strxcpy( outb, c, outb_size); return PASS; } /*-------------------------------------------------------------- ** parseSelection_r() - search a list for item. ** Return: >= 0 = the index of the matching item. ** FAIL = Item is not in list. **-------------------------------------------------------------- */ int parseSelection_r( char * buf, /* parameter for item to locate */ char * tok, /* token for parsing */ char **st_ptr, /* pointer for strtok_r() */ char ** list /* This list must be NULL terminaled */ ) { int i; char *c; if( (c = strtok_r( buf, tok, st_ptr) ) == NULL) return FAIL; for( i=0; list[i] != NULL; i++) { if( !strcasecmp( c, list[i] )) return i; } return FAIL; } /*------------------------------------------------------------- ** my_atol() - convert a string to a long. The string s ** must consist of '[white space][+-] digits [white spaces]' ** returns error: 0 = noerror; ** -1 = invalid char in string **------------------------------------------------------------- */ int my_atol( char *s, long *l ) { char *start; int cnt; if( s == NULL) return -1; while( isspace( (int) *s) ) s++; /* Skip leading spaces */ start = s; if( *s=='-' || *s=='+' ) s++; /* First char can be a signed */ cnt = 0; while( isdigit( (int)*s ) ) /* Only allow decimal digits */ { s++; cnt++; } if( !cnt ) return -1; /* Allow ONLY trailing white spaces */ while( *s ) if( isspace( (int)*s ) ) s++; else return -1; *l = strtol( start, (char**) NULL, 10 ); return 0; } /*---------------------------------------------------------- ** btoss( s ) - Create a string of 0's and 1's based on the ** bit pattern in s. ** Note: s should be at least char[40]; **---------------------------------------------------------- */ char * btoss ( char * s, unsigned short l ) { int i; unsigned short mask; char * cptr; mask = 0x8000; cptr = s; for( i=0; i<16; i++) { *cptr++ = ( l & mask ? '1' : '0' ); if( (i % 4)==3 ) *cptr++ = ' '; mask >>= 1; } *cptr = 0; return s; } /*---------------------------------------------------------- ** btosl( s ) - Create a string of 0's and 1's based on the ** bit pattern in l. ** Note: s should be at least char[40]; ** returns s. **---------------------------------------------------------- */ char * btosl ( char * s, unsigned long l ) { int i; unsigned long mask; char * cptr; mask = 0x80000000; cptr = s; for( i=0; i<32; i++) { *cptr++ = ( l & mask ? '1' : '0' ); if( (i % 4)==3 ) *cptr++ = ' '; mask >>= 1; } *cptr = 0; return s; } /************************************************************************/ /* copied from stargrasp */ /************************************************************************/ /*------------------------------------------------------------- ** simple_strtoul() - string to unsinged long conversion **------------------------------------------------------------- */ unsigned long simple_strtoul( const char *cp, /* I: starts scaning this string */ char **endp, /* O: returns address where scanning stopped */ unsigned int base /* I: base for char to long conversion, ie: 8, 10, 16 */ ) { unsigned long result = 0,value; if (*cp == '0') { cp++; if ((*cp == 'x') && isxdigit(cp[1])) { base = 16; cp++; } if (!base) { base = 8; } } if (!base) { base = 10; } while ( isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) ? toupper(*cp) : *cp)-'A'+10) < base) { result = result*base + value; cp++; } if (endp) *endp = (char *)cp; return result; } /*------------------------------------------------------------- ** simple_strtol() - string to long conversion **------------------------------------------------------------- */ long simple_strtol( const char *cp, /* I: starts scaning this string */ char **endp, /* O: returns address where scanning stopped */ unsigned int base /* I: base for char to long conversion, ie: 8, 10, 16 */ ) { if(*cp=='-') return -simple_strtoul(cp+1,endp,base); return simple_strtoul(cp,endp,base); } /*--------------------------------------------------------------------- ** cli_argv_ function to support (int argc, char **argv) arguments **--------------------------------------------------------------------- */ #define cli_malloc malloc #define cli_realloc realloc #ifndef TRUE #define FALSE (0) #define TRUE (1) #define BOOLEAN int #endif void cli_argv_free(char** cargv) { if (cargv) { if (cargv[0]) free(cargv[0]); free(cargv); } } static char** cli_argv_internal(int* argc, const char* args, BOOLEAN keep_quotes) { char* p; /* temporary working pointer */ char** cargv; /* pointers into rtn */ char quote_char='\0'; int arg_siz, arg_cnt, len; cargv = (char**)cli_malloc(sizeof(char*) * (arg_siz=32)); if ( cargv == NULL) return NULL; arg_cnt = 0; /* * Skip white space at beginning of line */ while (args && *args<=' ' && *args!='\0') args++; if ( args != NULL && (len = strlen(args)) != 0 ) { p = (char*)cli_malloc(len+1); if (p == NULL) { free(cargv); return NULL; } while (*args != '\0') { /* * Re-allocate more slots in cargv if needed. */ if ( arg_cnt >= arg_siz ) cargv = (char**)cli_realloc(cargv, sizeof(char*) * (arg_siz+=32)); if (cargv == NULL) { free(p); return NULL; } cargv[arg_cnt++] = p; while ( *args != '\0' && ( quote_char || *args > ' ' ) ) { if ( *args == quote_char ) /* End-quote reached */ { if (keep_quotes) *p++ = quote_char; quote_char = '\0'; args++; } else if ( *args == '"' || *args == '\'' ) /* Start-quote */ { quote_char = *args++; if (keep_quotes) *p++ = quote_char; } else if ( *args == '\\' && *(args+1) ) /* Literal character */ { args++; /* Skip the backslash */ *p++ = *args++; } else { *p++ = *args++; } } *p++ = '\0'; /* Terminate the (possibly) de-quoted, split argument */ while ( *args <= ' ' && *args != '\0' ) args++; /* skip white between and after arguments */ } } cargv[arg_cnt] = NULL; /* store a NULL at the end of the argument list */ if (argc!=NULL) *argc = arg_cnt; /* return a copy of arg_cnt if requested */ return cargv; /* return the argument array */ } char** cli_argv(int* argc, const char* args) { return cli_argv_internal(argc, args, /*keep_quotes=*/FALSE); } /*------------------------------------ ** ticks2usec() - mimic a uboot ticks2usec function ** get_ticks() - mimic a uboot function to get CPU tick counter value ** Note: SG controller has a 300MHz cpu, counter toggles once very CPU clock ** 1 tick is 003.333 nsec. **------------------------------------ */ unsigned long long ticks2usec (unsigned long long ticks) { double d = 0.003333333 * ticks; return d; } unsigned long long get_ticks( void ) { static int firsttime=1; static struct timespec start; struct timespec now; long long nsec; if( firsttime ) { clock_gettime( CLOCK_REALTIME, &start ); memcpy( &now, &start, sizeof(struct timespec)); firsttime = 0; } else { clock_gettime( CLOCK_REALTIME, &now ); } /* get elapse nanoseconds */ nsec = 1000000000LL * (now.tv_sec - start.tv_sec); nsec += (now.tv_nsec - start.tv_nsec); /* convert nanoseconds to tics */ return (long long) ( (double)nsec / 3.333); } /*------------------------------------------------------------------ ** clock_elapse_sec() - calculates elapsed sec (as double) ** between two timespec structures (see man clock_gettime). **------------------------------------------------------------------ */ double clock_elapse_sec( struct timespec *start, struct timespec *end) { long sec; long nsec; double d; sec = end->tv_sec - start->tv_sec; nsec = end->tv_nsec - start->tv_nsec; d = sec; // start with seconds d += nsec/1000000000.0; // convert nsec to sec and add in (OK if negative) return d; }