On Unix, is there a command to display a file's modification time, precise to the second?
On Linux this is easily done with a "stat -c %y", which returns something like 2009-11-27 11:36:06.000000000 +0100. I found no equivalent on Unix.
I found this:
ls --time-style='+%d-%m-%Y %H:%M:%S' -l
Which exports something like this:
root:~# ls --time-style='+%d-%m-%Y %H:%M:%S' -l
total 0
-rw-r--r-- 1 root root 0 16-04-2015 23:14:02 other-file.txt
-rw-r--r-- 1 root root 0 16-04-2015 23:13:58 test.txt
According to the man page on my Mac (which has the BSD standard version of stat) you can get the epoch time version of the modification in seconds with:
stat -f %m /etc/passwd
Or if you want to print that out in hours:mins:secs you can do this:
perl -e "print scalar(localtime(`stat -f %m /etc/passwd`))"
The following gives you last modified time in seconds since Epoch:
stat -c%Y <file>
The find command is a good source for all kinds of file information, including modification time to the second:
find /etc/passwd -maxdepth 0 -printf "%TY/%Tm/%Td %TH:%TM:%.2TS\n"
2011/11/21 13:41:36
The first argument can be a file. The maxdepth prevents searching if a directory name is given. The %T instructs it to print last modification time.
Some systems interpret %TS as a floating point seconds (e.g. 36.8342610). If you want fractional seconds use "%TS" instead of "%.2TS", but you may not see fractional seconds on every system.
For anyone facing the same issue, I found no solution (on HP-UX 11i anyway).
Ended up coding a personalized "ls -lh" for my needs. It's not that hard..
Prints something like :
- 664 rw-/rw-/r-- 1L expertNoob adm 8.37 kB 2010.08.24 12:11:15 findf1.c
d 775 rwx/rwx/r-x 2L expertNoob adm 96 B 2010.08.24 15:17:37 tmp/
- 775 rwx/rwx/r-x 1L expertNoob adm 16 kB 2010.08.24 12:35:30 findf1
- 775 rwx/rwx/r-x 1L expertNoob adm 24 kB 2010.09.14 19:45:20 dir_info
- 444 r--/r--/r-- 1L expertNoob adm 9.01 kB 2010.09.01 11:23:41 getopt.c
- 664 rw-/rw-/r-- 1L expertNoob adm 6.86 kB 2010.09.01 11:24:47 getopt.o
- 664 rw-/rw-/r-- 1L expertNoob adm 6.93 kB 2010.09.14 19:37:44 findf1.o
l 775 rwx/rwx/r-x 1L expertNoob adm 6 B 2010.10.06 17:09:01 test1 -> test.c
- 664 rw-/rw-/r-- 1L expertNoob adm 534 B 2009.03.26 15:34:23 > test.c
d 755 rwx/r-x/r-x 25L expertNoob adm 8 kB 2009.05.20 15:36:23 zip30/
Here it is :
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <dirent.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <locale.h>
#include <langinfo.h>
#include <stdio.h>
//#include <stdint.h>
#include <limits.h> // PATH_MAX
#include <stdarg.h>
#include "getopt.h"
static short START_VSNBUFF=16;
// This is bformat from Better String library (bstrlib), customized
int strformat (char ** str, const char * fmt, ...) {
va_list arglist;
char * buff;
int n, r;
/* Since the length is not determinable beforehand, a search is
performed using the truncating "vsnprintf" call (to avoid buffer
overflows) on increasing potential sizes for the output result. */
if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF;
if ( NULL == ( buff = (char *) malloc((n + 2)*sizeof(char)) ) ) {
n = 1;
if ( NULL == ( buff = (char *) malloc((n + 2)*sizeof(char)) ) ) {
fprintf( stderr, "strformat: not enough memory to format string\n" );
return -1;
}
}
for (;;) {
va_start (arglist, fmt);
r = vsnprintf (buff, n + 1, fmt, arglist); // n+1 chars: buff[0]..buff[n], n chars from arglist: buff[n]='\0'
va_end (arglist);
buff[n] = (unsigned char) '\0'; // doesn't hurt, especially strlen!
if ( strlen(buff) < n ) break;
if (r > n) n = r; else n += n;
if ( NULL == ( buff = (char *) realloc( buff, (n + 2)*sizeof(char) ) ) ) {
free(buff);
fprintf( stderr, "strformat: not enough memory to format string\n" );
return -1;
}
}
if( NULL != *str ) free(*str);
*str = buff;
return 0;
}
int printFSObjectInfo( const char * path, const char * name ) {
struct stat statbuf;
struct passwd *pwd;
struct group *grp;
struct tm *tm;
char datestring[256];
char *type = "? ";
char *fbuf = NULL;
double size = 0;
const char *units[] = {"B ", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
int i = 0;
char owner[] = "---", group[] = "---", others[] = "---";
/* Get entry's information. */
if ( -1 == lstat( path, &statbuf ) ) {
fprintf( stderr, "printFSObjectInfo: error: can't stat %s\n", path );
if( 0 == strformat( &fbuf, "lstat() said: %s", path ) ) { perror(fbuf); return -1; }
}
// File type
if( S_ISREG(statbuf.st_mode) ) type = "-"; // regular file
if( S_ISDIR(statbuf.st_mode) ) { // directory
type="d";
if( S_ISCDF(statbuf.st_mode) ) type = "hd"; // hidden dir
}
if( S_ISBLK(statbuf.st_mode) ) type = "b"; // block special
if( S_ISCHR(statbuf.st_mode) ) type = "c"; // character special
if( S_ISFIFO(statbuf.st_mode) ) type = "f"; // pipe or FIFO
if( S_ISLNK(statbuf.st_mode) ) type = "l"; // symbolic link
if( S_ISSOCK(statbuf.st_mode) ) type = "s"; // socket
if( S_ISNWK(statbuf.st_mode) ) type = "n"; // network special
printf( "%2s ", type );
/* Print out type, permissions, and number of links. */
//printf("%10.10s", sperm (statbuf.st_mode));
if( S_IRUSR & statbuf.st_mode ) owner[0] = 'r';
if( S_IWUSR & statbuf.st_mode ) owner[1] = 'w';
if( S_IXUSR & statbuf.st_mode ) owner[2] = 'x';
if( S_IRGRP & statbuf.st_mode ) group[0] = 'r';
if( S_IWGRP & statbuf.st_mode ) group[1] = 'w';
if( S_IXGRP & statbuf.st_mode ) group[2] = 'x';
if( S_IROTH & statbuf.st_mode ) others[0] = 'r';
if( S_IWOTH & statbuf.st_mode ) others[1] = 'w';
if( S_IXOTH & statbuf.st_mode ) others[2] = 'x';
//printf( "\n%o\n", statbuf.st_mode );
printf( "%3o %s/%s/%s ", 0777 & statbuf.st_mode, owner, group, others );
printf("%4dL", statbuf.st_nlink);
/* Print out owner's name if it is found using getpwuid(). */
if ((pwd = getpwuid(statbuf.st_uid)) != NULL)
printf(" %-8.8s", pwd->pw_name);
else
printf(" %-8d", statbuf.st_uid);
/* Print out group name if it is found using getgrgid(). */
if ((grp = getgrgid(statbuf.st_gid)) != NULL)
printf(" %-8.8s", grp->gr_name);
else
printf(" %-8d", statbuf.st_gid);
/* Print size of file. */
//printf(" %9d", (int)statbuf.st_size);
i = 0;
size = (double) statbuf.st_size;
while (size >= 1024) {
size /= 1024;
i++;
}
if( 0 == (double)(size - (long) size) )
printf( "%7d %-2s", (long)size, units[i] );
else printf( "%7.2f %-2s", size, units[i] );
tm = localtime(&statbuf.st_mtime);
/* Get localized date string. */
strftime(datestring, sizeof(datestring), "%Y.%m.%d %T", tm); // nl_langinfo(D_T_FMT)
if ( 0 == strcmp(name, "\n") )
printf(" %s > %s", datestring, path);
else {
if( 0 == strcmp(type, "d") ) printf(" %s %s/", datestring, name);
else printf(" %s %s", datestring, name);
}
if( 0 == strcmp(type, "l") ) {
char buf[1+PATH_MAX];
if( -1 == readlink( path, buf, (1+PATH_MAX) ) ) {
fprintf( stderr, "printFSObjectInfo: error: can't read symbolic link %s\n", path);
if( 0 == strformat( &fbuf, "readlink() said: %s:", path ) ) { perror(fbuf); return -2; }
}
else {
lstat( buf, &statbuf ); // want errno, a symlink may point to non-existing object
if(errno == ENOENT) printf(" -> %s [!no such file!]\n", buf );
else {
printf(" -> %s\n", buf );
if ( 0 != strcmp(name, "\n") ) printFSObjectInfo( buf, "\n" );
}
}
}
else printf("\n");
return 0;
}
int main(int argc, char **argv) {
struct dirent *dp;
struct stat statbuf;
char *path = NULL; //[1+PATH_MAX];
char *fbuf = NULL;
char *pathArg = NULL;
if( argc == 1 || 0 == strlen(argv[1]) ) pathArg = ".";
else pathArg = argv[1];
if ( lstat( pathArg, &statbuf ) == -1 ) {
printf("%s: error: can't stat %s\n", argv[0], pathArg);
if( 0 == strformat( &fbuf, "stat() said: %s", pathArg ) ) perror(fbuf);
exit(2);
}
if( S_ISDIR(statbuf.st_mode) ) {
DIR *dir = opendir( pathArg );
if( NULL == dir ) {
fprintf( stderr, "%s: error: can't open %s\n", argv[0], pathArg );
if( 0 != strformat( &fbuf, "opendir() said: %s", pathArg ) ) exit(5);
perror(fbuf);
exit(4);
}
/* Loop through directory entries. */
while ( (dp = readdir(dir)) != NULL ) {
if( 0!= strformat( &path, "%s/%s", pathArg, dp->d_name ) ) continue;
printFSObjectInfo( path, dp->d_name );
}
closedir(dir);
} else printFSObjectInfo( pathArg, pathArg );
return 0;
}
In printFSObjectInfo() you have full functionality of lstat() system call, you can customize this to your wishes.
Be well.
Try a perl one-liner:
perl -e '#d=localtime ((stat(shift))[9]); printf "%02d-%02d-%04d %02d:%02d:%02d\n", $d[3],$d[4]+1,$d[5]+1900,$d[2],$d[1],$d[0]' your_file_to_show_the_date_for.your_extension
ls -le works if you need only HH:MM:SS
On Mac OS X (tested on 10.10.5 Yosemite thru 10.12.4 Sierra):
prompt> ls -lT
total 0
-rw-r--r-- 1 youruser staff 0 Sep 24 10:28:30 2015 my_file_1.txt
-rw-r--r-- 1 youruser staff 0 Sep 24 10:28:35 2015 my_file_2.txt
If you are using HP-UX:
Ok let's say that the name of the file is "junk". On HP-UX you can do:
perl -e '#d=localtime ((stat(shift))[9]); printf "%4d-%02d-%02d %02d:%02d:%02d\n", $d[5]+1900,$d[4]+1,$d[3],$d[2],$d[1],$d[0]' junk
And yes, perl comes with HP-UX. It is in /usr/contrib. But you may have a more recent version in /usr/local or /opt.
Source: Perderabo
Today I encountered the same issue on an old version of HP-UX. The stat program was not part of the installation. (just the C version)
The quickest solution for me was to use a tool such as Tectia file transfer running on my laptop, without actually doing any copying, It converts the time of last modification for you from HP-UX and provides dates and times for all files once you have logged into UNIX.
Possibly this works with other similar graphic based file transfer tools, but I have not tried yet.
On AIX the istat command does this:
machine:~/support> istat ../core
Inode 30034 on device 32/3 File
Protection: rw-rw-r--
Owner: 500(group) Group: 500(user)
Link count: 1 Length 10787748 bytes
Last updated: Wed Feb 22 13:54:28 2012
Last modified: Wed Feb 22 13:54:28 2012
Last accessed: Wed Feb 22 19:58:10 2012
Seconds:
date +%s -r /etc/passwd
Or, with more precision (up to nanosecond precision), if your filesystem supports it:
date +%s.%N -r /etc/passwd
Related
How can I prevent aborted builds when a previously applied patch is detected without:
simply ignoring all failed patches
requiring user input
Patch itself is capable of identifying a previously applied patch. There's got to be a way to avoid the non-zero exit status on previously applied patches, right?
This doesn't work:
yes 'n' | patch -p<w/e> -i <w/e>
Because patch reads from /dev/tty (I'm guessing) instead of stdin. Even if it did read from stdin, it still gives an exit status of 1.
It seems like I'm missing something. I can't be the first to have run into this problem.
I think I may have just solved my problem.
diff --git a/src/common.h b/src/common.h
index 9e355fe..e1b1555 100644
--- a/src/common.h
+++ b/src/common.h
## -108,8 +108,10 ## XTERN bool force;
XTERN bool batch;
XTERN bool noreverse;
XTERN bool reverse;
+XTERN bool applied;
XTERN enum { DEFAULT_VERBOSITY, SILENT, VERBOSE } verbosity;
XTERN bool skip_rest_of_patch;
+XTERN bool applied_is_cause;
XTERN int strippath;
XTERN bool canonicalize;
XTERN int patch_get;
diff --git a/src/patch.c b/src/patch.c
index a60e631..3d375b3 100644
--- a/src/patch.c
+++ b/src/patch.c
## -613,7 +613,8 ## main (int argc, char **argv)
if (fstat (fileno (rejfp), &rejst) != 0 || fclose (rejfp) != 0)
write_fatal ();
rejfp = NULL;
- somefailed = true;
+ if (! somefailed && ! (applied && applied_is_cause))
+ somefailed = true;
say ("%d out of %d hunk%s %s", failed, hunk, "s" + (hunk == 1),
skip_rest_of_patch ? "ignored" : "FAILED");
if (outname && (! rejname || strcmp (rejname, "-") != 0)) {
## -629,7 +630,7 ## main (int argc, char **argv)
rej[len - 1] = '#';
simple_backup_suffix = s;
}
- if (! dry_run)
+ if (! dry_run && ! (applied && applied_is_cause))
{
say (" -- saving rejects to file %s\n", quotearg (rej));
if (rejname)
## -706,9 +707,10 ## reinitialize_almost_everything (void)
reverse = reverse_flag_specified;
skip_rest_of_patch = false;
+ applied_is_cause = false;
}
-static char const shortopts[] = "bB:cd:D:eEfF:g:i:l"
+static char const shortopts[] = "abB:cd:D:eEfF:g:i:l"
#if 0 && defined ENABLE_MERGE
"m"
#endif
## -716,6 +718,7 ## static char const shortopts[] = "bB:cd:D:eEfF:g:i:l"
static struct option const longopts[] =
{
+ {"applied", no_argument, NULL, 'a'},
{"backup", no_argument, NULL, 'b'},
{"prefix", required_argument, NULL, 'B'},
{"context", no_argument, NULL, 'c'},
## -777,6 +780,7 ## static char const *const option_help[] =
"",
" -N --forward Ignore patches that appear to be reversed or already applied.",
" -R --reverse Assume patches were created with old and new files swapped.",
+" -a --applied Ignore error and save no rejects on applied or reversed patch.",
"",
" -i PATCHFILE --input=PATCHFILE Read patch from PATCHFILE instead of stdin.",
"",
## -869,6 +873,9 ## get_some_switches (void)
while ((optc = getopt_long (Argc, Argv, shortopts, longopts, (int *) 0))
!= -1) {
switch (optc) {
+ case 'a':
+ applied = true;
+ break;
case 'b':
make_backups = true;
/* Special hack for backward compatibility with CVS 1.9.
diff --git a/src/util.c b/src/util.c
index ee88c13..432bc5c 100644
--- a/src/util.c
+++ b/src/util.c
## -1056,6 +1056,7 ## ok_to_reverse (char const *format, ...)
{
say (" Skipping patch.\n");
skip_rest_of_patch = true;
+ applied_is_cause = true;
}
else if (force)
{
## -1079,6 +1080,7 ## ok_to_reverse (char const *format, ...)
if (verbosity != SILENT)
say ("Skipping patch.\n");
skip_rest_of_patch = true;
+ applied_is_cause = true;
}
}
}
I'm trying to test WP plugin with Alt-Ergo on a fairly complex function. Unfortunately, I am not able to figure out what's wrong with the "basic" behavior given below.
This behavior should be true because there is no other place tenumRMode is updated except the first conditional statement's else section.
The wierd thing is that if I comment some lines arbitrarily I always get "valid" from Alt-ergo.
Any comments?
/*# behavior basic:
# assumes fRrValue == 0;
# ensures tenumRMode == SS_A_MODE;
#
*/
[formal_verification]$ frama-c -wp -wp-rte -wp-bhv=basic foo.c -wp-out t -lib-entry -main foo -wp-model ref -wp-timeout=50 -wp-fct=foo -wp-out t
[kernel] preprocessing with "gcc -C -E -I. foo.c"
[wp] Running WP plugin...
[rte] annotating function foo
[wp] Collecting axiomatic usage
[wp] Collecting variable usage
[wp] 1 goal scheduled
[wp] [Alt-Ergo] Goal typed_ref_foo_basic_post : Unknown (Qed:20ms)
typedef unsigned char BOOL;
#define TRUE 1
#define FALSE 0
typedef unsigned char uint8;
typedef unsigned short int uint16;
typedef unsigned long uint32;
uint16 F_MIN_R = 15;
const uint8 RESP_STATE = 30;
typedef enum
{
RESP_MODE,
SS_A_MODE
}tenumMode;
tenumMode tenumRMode;
BOOL gbCaMStatus;
BOOL gbCaaStatus;
uint8 mnPb;
BOOL mbApLYRange;
BOOL mbApLRange;
float gfApYLineSlope;
float gfApYLineConst;
float gfApRLineSlope;
float gfApRLineConst;
float mfAp;
uint16 almC;
uint16 nApLYL = 0;
uint16 nApLRL = 0;
uint16 Ap_Y_L_Ui = 0;
uint16 Ap_R_L_Ui = 0;
float fCaValue=0.0;
float fRrValue = 0.0;
uint16 nCaLYL=0;
uint16 nCaLRL=0;
/*# behavior basic:
# assumes fRrValue == 0;
# ensures tenumRMode == SS_A_MODE;
#
*/
void foo()
{
float mfNewAp = 0;
BOOL bYAp = FALSE;
BOOL bRAp = FALSE;
BOOL bApAlmC = FALSE;
if (fRrValue != 0)
{
/* Some code here */
}
else
{
if (mnPb == 1)
{
mfAp = RESP_STATE;
mnPb = 2;
}
tenumRMode = SS_A_MODE;
}
if ( (mfAp >= F_MIN_R) &&
((gbCaMStatus == TRUE) && (gbCaaStatus == FALSE)) )
{
bApAlmC = TRUE;
almC = 1;
}
else
{
almC = 0;
}
if ( (bApAlmC == TRUE)
&& (mfAp < nApLYL)
&& (fCaValue >= nCaLYL) )
{
float fmultval = 0;
fmultval = gfApYLineSlope*fCaValue;
mfNewAp = fmultval + gfApYLineConst;
if (mfAp >= mfNewAp)
bYAp = TRUE;
else
bYAp = FALSE;
Ap_Y_L_Ui = (uint16)mfNewAp;
}
if ((bApAlmC == TRUE) && (fCaValue > (float)nCaLYL))
{
mfNewAp = ((gfApYLineSlope*fCaValue) + gfApYLineConst);
if (mfNewAp < (float)nApLYL);
Ap_Y_L_Ui = (uint16)mfNewAp;
}
else if ((bApAlmC == TRUE) && (fCaValue <= (float)nCaLYL))
Ap_Y_L_Ui = F_MIN_R;
if ( (bApAlmC == TRUE) && (fCaValue >= nCaLRL) )
{
float fmultval = 0;
fmultval = gfApRLineSlope*fCaValue;
mfNewAp = fmultval + gfApRLineConst;
if (mfAp >= mfNewAp)
bRAp = TRUE;
else
bRAp = FALSE;
Ap_R_L_Ui = (uint16)mfNewAp;
}
else if ( (bApAlmC == TRUE) && (fCaValue < nCaLRL) )
Ap_R_L_Ui = F_MIN_R;
if ( (mfAp >= nApLYL)
|| ((bApAlmC == TRUE) && (fCaValue < nCaLYL))
|| ((bYAp == TRUE)
&& (gbCaMStatus == TRUE) && (gbCaaStatus == FALSE) ) )
{
mbApLYRange = TRUE;
}
else
mbApLYRange = FALSE;
if ( (mfAp >= nApLRL)
|| ((bApAlmC == TRUE) && (fCaValue < nCaLRL))
|| ((bRAp == TRUE)
&& (gbCaMStatus == TRUE) && (gbCaaStatus == FALSE) ) )
{
/* Some code here */
}
}
Which versions of Alt-ergo and Frama-C are you using ? I tried your example using Frama-C Oxygen-20120901 and Alt-Ergo version 0.95.2 (installed via OPAM) and I got:
$ frama-c -wp -wp-rte -lib-entry -main foo foo.c -wp-bhv=basic
[kernel] preprocessing with "gcc -C -E -I. foo.c"
[wp] Running WP plugin...
[wp] Collecting axiomatic usage
foo.c:51:[wp] warning: [get_strategies] no behaviors found
foo.c:51:[wp] warning: [get_strategies] no behaviors found
[rte] annotating function foo
[wp] 1 goal scheduled
[wp] [Alt-Ergo] Goal store_foo_basic_post : Unknown
When I tried directly Alt-Ergo (v. 0.95.2), I got:
$ alt-ergo store_foo_basic_post_po_ergo.why
File "store_foo_basic_post_po_ergo.why", line 1220, characters 22-24:syntax error
The VC is proved after fixing the syntax erros by hand. I think Alt-Ergo v. >= 0.95 is not compatible with Frama-C Oxygen. BTW, I don't know way OPAM had'nt installed the latest version of Frama-C on my computer (i.e. Fluorine-20130601)
-- Regards
I am new to OpenBSD. I have worked on Linux before. I am looking for the directory where I can find the information about the processes running currently. In Linux, we have /proc directory where the entire list is present. But I can not find a similar setup in OpenBSD 4.6. I know there are commands like ps, top and sysctl but I want to get that information through a C code.
procfs in the BSDs is either deprecated or removed altogether, sorry.
That being said, it's also quite usual to have the sources for your system under /usr/src, so you can look at them if you really need to.
Or you can just browse them on the web, eg http://bxr.su/o/bin/ps/ps.c
You can use sysctl to get the running processes in an array of kinfo_proc structures, this type is defined in:
/usr/include/sys/sysctl.h
The top command uses a function named getprocs that works this way, it's defined in:
/usr/src/usr.bin/top/machine.c
The next utility outputs information of all running processes using a slightly modified version of getprocs:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <kvm.h>
#include <sys/sysctl.h>
#define TRUE 1
#define FALSE 0
struct kinfo_proc * getprocs( int * count, int threads )
{
struct kinfo_proc * procbase = NULL ;
unsigned int maxslp ;
size_t size = sizeof( maxslp ) ;
int maxslp_mib[] = { CTL_VM, VM_MAXSLP } ;
int mib[6] =
{
CTL_KERN,
KERN_PROC,
threads ? KERN_PROC_KTHREAD | KERN_PROC_SHOW_THREADS : KERN_PROC_KTHREAD,
0,
sizeof( struct kinfo_proc ),
0
} ;
if( sysctl( maxslp_mib, 2, &maxslp, &size, NULL, 0 ) == -1 )
{
perror( "list" ) ;
return NULL ;
}
retry:
if( sysctl( mib, 6, NULL, &size, NULL, 0 ) == -1 )
{
perror( "list" ) ;
return NULL ;
}
size = 5 * size / 4 ; /* extra slop */
procbase = (struct kinfo_proc *)malloc( size ) ;
if( procbase == NULL )
{
perror( "list" ) ;
return NULL ;
}
mib[5] = (int)( size / sizeof( struct kinfo_proc ) ) ;
if( sysctl( mib, 6, procbase, &size, NULL, 0 ) )
{
if( errno == ENOMEM )
{
free( procbase ) ;
goto retry;
}
perror( "list" ) ;
return NULL ;
}
*count = (int)( size / sizeof( struct kinfo_proc ) ) ;
return procbase ;
}
int showinfo( int threads )
{
struct kinfo_proc * list, * proc ;
int count, i ;
if( ( list = getprocs( &count, threads ) ) == NULL )
{
return 1 ;
}
proc = list ;
if( threads )
{
for( i = 0 ; i < count ; ++i, ++proc )
{
if( proc->p_tid != -1 )
{
printf( "%s: pid: %d (tid: %d)\n", proc->p_comm, proc->p_pid, proc->p_tid ) ;
}
}
}
else
{
for( i = 0 ; i < count ; ++i, ++proc )
{
printf( "%s: pid: %d\n", proc->p_comm, proc->p_pid ) ;
}
}
return 0 ;
}
int main( int argc, char * argv[] )
{
if( argc == 1 )
{
return showinfo( FALSE ) ;
}
else if( argc == 2 && ( !strcmp( argv[1], "-t" ) || !strcmp( argv[1], "--threads" ) ) )
{
return showinfo( TRUE ) ;
}
else
{
printf( "Usage:\n" ) ;
printf( " list [-h] [-t]\n\n" ) ;
printf( "Options:\n" ) ;
printf( " -h, --help Print this information\n" ) ;
printf( " -t, --threads Show threads\n\n" ) ;
return 0 ;
}
}
I have two bytes that are made up of two 4-bit numbers packed together. I need to know if either of the two numbers from the first byte matches either of the numbers from the second byte. Zero is considered null and shouldn't match itself.
Obviously, I can do this by unpacking the numbers and comparing them one by one:
a = 0b10100101;
b = 0b01011111; // should have a match because 0101 is in both
a1 = a>>4; a2 = a&15;
b1 = b>>4; b2 = b&15;
return (a1 != 0 && (a1 == b1 || a1 == b2)) || (a2 != 0 && (a2 == b1 || a2 == b2));
// ( true && ( false || false )) || ( true && ( true || false ))
// ( true && false ) || ( true && true )
// false || true
// TRUE
However I'm just wondering if anyone knows of a cleaner way to do this?
Precompute the answer and store it in a lookup table. The key to your table is 16 bits ((a<<8)+b). It need only be 1 bit output (uses 8K), but you could use 8 bits for simplicity (uses 64K).
A cleaner way would be to get rid of that hard-to-parse expression and make the code more readable.
def sameNybble (a, b):
# Get high and low nybbles.
ahi = (a >> 4) & 15 ; alo = a & 15;
bhi = (b >> 4) & 15 ; blo = b & 15;
# Only check ahi if non-zero, then check against bhi/blo
if ahi != 0:
if ahi == bhi or ahi == blo:
return true
# Only check alo if non-zero, then check against bhi/blo
if alo != 0:
if alo == bhi or alo == blo:
return true
# No match
return false
Any decent optimising compiler will basically give you the same underlying code so it's sometimes better to optimise for readability.
Here is a solution in C++ that is more concise and 1.6 times faster. It generates code that is friendlier for high end microprocessors with deep pipelines and complex branch prediction logic. It generates true/false with no comparison/branches and no table lookup (no data cache miss).
A nibble has 4 bits and therefore holds one of 16 values, I map the two nibbles in each of the inputs to an unsigned value (which has at least 16 bits) with bits set in the corresponding bit positions indicating both nibble values present in the input. I then AND the two bitsets, thus computing the intersection of the sets. The last AND discards any matches with nibble 0.
inline unsigned set( unsigned char X ) {
return (1 << (X & 15)) | (1 << (X >> 4));
}
// Return true if a nibble in 'A' matches a non-null nibble in 'B'
inline bool match( unsigned char A, unsigned char B ) {
return set( A ) & set( B ) & ~set( 0 );
}
I've timed it on an Intel Xeon X5570 # 2.93GHz and it is 1.6x faster than the original in the question. Here's the code I used to time it:
#include <time.h>
#include <iostream>
bool original( unsigned char A, unsigned char B ) {
unsigned char a1 = A >> 4;
unsigned char a2 = A & 15;
unsigned char b1 = B >> 4;
unsigned char b2 = B & 15;
return (a1 != 0 && (a1 == b1 || a1 == b2)) || (a2 != 0 && (a2 == b1 || a2 == b2));
}
static inline unsigned set( unsigned char X ) {
return (1 << (X & 15)) | (1 << ((X >> 4)&15));
}
bool faster( unsigned char A, unsigned char B ) {
return set( A ) & set( B ) & ~set( 0 );
}
class Timer {
size_t _time;
size_t & _elapsed;
size_t nsec() {
timespec ts;
clock_gettime( CLOCK_REALTIME, &ts );
return ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
}
public:
Timer(size_t & elapsed) : _time(nsec()), _elapsed(elapsed) {}
~Timer() { _elapsed = nsec() - _time; }
};
int main()
{
size_t original_nsec, faster_nsec;
const size_t iterations = 200000000ULL;
size_t count = 0;
{ Timer t(original_nsec);
for(size_t i=0; i < iterations; ++i) {
count += original( 0xA5 , i & 0xFF );
}
}
{ Timer t(faster_nsec);
for(size_t i=0; i < iterations; ++i) {
count += faster( 0xA5 , i & 0xFF );
}
}
std::cout << double(original_nsec) / double(faster_nsec)
<< "x faster" << std::endl;
return count > 0 ? 0 : 1;
}
Here's the output:
$ g++ -o match -O3 match.cpp -lrt && ./match
1.61564x faster
$
How do I convert an int, n, to a string so that when I send it over the serial, it is sent as a string?
This is what I have so far:
int ledPin=13;
int testerPin=8;
int n=1;
char buf[10];
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(testerPin, OUTPUT);
Serial.begin(115200);
}
void loop()
{
digitalWrite(ledPin, HIGH);
sprintf(buf, "Hello!%d", n);
Serial.println(buf);
delay(500);
digitalWrite(ledPin, LOW);
delay(500);
n++;
}
Use like this:
String myString = String(n);
You can find more examples here.
use the itoa() function included in stdlib.h
char buffer[7]; //the ASCII of the integer will be stored in this char array
itoa(-31596,buffer,10); //(integer, yourBuffer, base)
You can simply do:
Serial.println(n);
which will convert n to an ASCII string automatically. See the documentation for Serial.println().
You just need to wrap it around a String object like this:
String numberString = String(n);
You can also do:
String stringOne = "Hello String"; // using a constant String
String stringOne = String('a'); // converting a constant char into a String
String stringTwo = String("This is a string"); // converting a constant string into a String object
String stringOne = String(stringTwo + " with more"); // concatenating two strings
String stringOne = String(13); // using a constant integer
String stringOne = String(analogRead(0), DEC); // using an int and a base
String stringOne = String(45, HEX); // using an int and a base (hexadecimal)
String stringOne = String(255, BIN); // using an int and a base (binary)
String stringOne = String(millis(), DEC); // using a long and a base
This is speed-optimized solution for converting int (signed 16-bit integer) into string.
This implementation avoids using division since 8-bit AVR used for Arduino has no hardware DIV instruction, the compiler translate division into time-consuming repetitive subtractions. Thus the fastest solution is using conditional branches to build the string.
A fixed 7 bytes buffer prepared from beginning in RAM to avoid dynamic allocation. Since it's only 7 bytes, the cost of fixed RAM usage is considered minimum. To assist compiler, we add register modifier into variable declaration to speed-up execution.
char _int2str[7];
char* int2str( register int i ) {
register unsigned char L = 1;
register char c;
register boolean m = false;
register char b; // lower-byte of i
// negative
if ( i < 0 ) {
_int2str[ 0 ] = '-';
i = -i;
}
else L = 0;
// ten-thousands
if( i > 9999 ) {
c = i < 20000 ? 1
: i < 30000 ? 2
: 3;
_int2str[ L++ ] = c + 48;
i -= c * 10000;
m = true;
}
// thousands
if( i > 999 ) {
c = i < 5000
? ( i < 3000
? ( i < 2000 ? 1 : 2 )
: i < 4000 ? 3 : 4
)
: i < 8000
? ( i < 6000
? 5
: i < 7000 ? 6 : 7
)
: i < 9000 ? 8 : 9;
_int2str[ L++ ] = c + 48;
i -= c * 1000;
m = true;
}
else if( m ) _int2str[ L++ ] = '0';
// hundreds
if( i > 99 ) {
c = i < 500
? ( i < 300
? ( i < 200 ? 1 : 2 )
: i < 400 ? 3 : 4
)
: i < 800
? ( i < 600
? 5
: i < 700 ? 6 : 7
)
: i < 900 ? 8 : 9;
_int2str[ L++ ] = c + 48;
i -= c * 100;
m = true;
}
else if( m ) _int2str[ L++ ] = '0';
// decades (check on lower byte to optimize code)
b = char( i );
if( b > 9 ) {
c = b < 50
? ( b < 30
? ( b < 20 ? 1 : 2 )
: b < 40 ? 3 : 4
)
: b < 80
? ( i < 60
? 5
: i < 70 ? 6 : 7
)
: i < 90 ? 8 : 9;
_int2str[ L++ ] = c + 48;
b -= c * 10;
m = true;
}
else if( m ) _int2str[ L++ ] = '0';
// last digit
_int2str[ L++ ] = b + 48;
// null terminator
_int2str[ L ] = 0;
return _int2str;
}
// Usage example:
int i = -12345;
char* s;
void setup() {
s = int2str( i );
}
void loop() {}
This sketch is compiled to 1,082 bytes of code using avr-gcc which bundled with Arduino v1.0.5 (size of int2str function itself is 594 bytes). Compared with solution using String object which compiled into 2,398 bytes, this implementation can reduce your code size by 1.2 Kb (assumed that you need no other String's object method, and your number is strict to signed int type).
This function can be optimized further by writing it in proper assembler code.
The solution is much too big. Try this simple one. Please provide a 7+ character buffer, no check made.
char *i2str(int i, char *buf){
byte l=0;
if(i<0) buf[l++]='-';
boolean leadingZ=true;
for(int div=10000, mod=0; div>0; div/=10){
mod=i%div;
i/=div;
if(!leadingZ || i!=0){
leadingZ=false;
buf[l++]=i+'0';
}
i=mod;
}
buf[l]=0;
return buf;
}
Can be easily modified to give back end of buffer, if you discard index 'l' and increment the buffer directly.
This simply work for me:
int bpm = 60;
char text[256];
sprintf(text, "Pulso: %d ", bpm);
//now use text as string
In Arduino, using the String keyword creates an object of the String class which has multiple versions of its constructor. If an integer is passed as an argument while instantiating, it contains the ASCII representation of the numbers.
int num = 12;
String intString = String(num);
// The value of intString should be "12"
Please check out the arduino String reference.
Here below is a self composed myitoa() which is by far smaller in code, and reserves a FIXED array of 7 (including terminating 0) in char *mystring, which is often desirable. It is obvious that one can build the code with character-shift instead, if one need a variable-length output-string.
void myitoa(int number, char *mystring) {
boolean negative = number>0;
mystring[0] = number<0? '-' : '+';
number = number<0 ? -number : number;
for (int n=5; n>0; n--) {
mystring[n] = ' ';
if(number > 0) mystring[n] = number%10 + 48;
number /= 10;
}
mystring[6]=0;
}
Serial.println(val)
Serial.println(val, format)
for more you can visit to the site of arduino
https://www.arduino.cc/en/Serial/Println
wish this will help you.
thanks!