mirror of https://gerrit.osmocom.org/asn1c
retaining old file if contents are the same
This commit is contained in:
parent
21d0000937
commit
4604d03d98
|
@ -7,6 +7,7 @@
|
|||
#include "asn1c_constraint.h"
|
||||
#include "asn1c_out.h"
|
||||
#include "asn1c_misc.h"
|
||||
#include "asn1c_compat.h"
|
||||
#include <asn1fix_export.h> /* Stuff exported by libasn1fix */
|
||||
|
||||
typedef struct tag2el_s {
|
||||
|
@ -1703,9 +1704,9 @@ emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_
|
|||
int using_type_name = 0;
|
||||
char *p;
|
||||
|
||||
OUT("/* %s defined in %s at line %d */\n",
|
||||
OUT("/* %s defined in %s near line %d */\n",
|
||||
MKID_nc(expr->Identifier),
|
||||
arg->mod->source_file_name, expr->_lineno);
|
||||
a1c_basename(arg->mod->source_file_name), expr->_lineno);
|
||||
if(HIDE_INNER_DEFS)
|
||||
OUT("static /* Use -fall-defs-global to expose */\n");
|
||||
OUT("asn_TYPE_descriptor_t asn_DEF_%s", MKID_nc(expr->Identifier));
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#endif
|
||||
|
||||
FILE *
|
||||
asn1c_open_file(const char *name, const char *ext) {
|
||||
asn1c_open_file(const char *name, const char *ext, char **opt_tmpname) {
|
||||
int created = 1;
|
||||
#ifndef WIN32
|
||||
struct stat sb;
|
||||
|
@ -22,22 +22,35 @@ asn1c_open_file(const char *name, const char *ext) {
|
|||
char *fname;
|
||||
size_t len;
|
||||
FILE *fp;
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* Compute filenames.
|
||||
*/
|
||||
len = strlen(name) + strlen(ext) + 1;
|
||||
len = strlen(name) + strlen(ext) + sizeof(".XXXXXX");
|
||||
fname = alloca(len);
|
||||
snprintf(fname, len, "%s%s", name, ext);
|
||||
ret = snprintf(fname, len, "%s%s%s", name, ext,
|
||||
opt_tmpname ? ".XXXXXX" : "");
|
||||
assert(ret > 0 && ret < len);
|
||||
|
||||
/*
|
||||
* Create files.
|
||||
*/
|
||||
fd = open(fname, O_CREAT | O_EXCL | O_WRONLY, DEFFILEMODE);
|
||||
if(fd == -1 && errno == EEXIST) {
|
||||
fd = open(fname, O_WRONLY, DEFFILEMODE);
|
||||
created = 0;
|
||||
if(opt_tmpname) {
|
||||
/*
|
||||
* Create temporary file.
|
||||
*/
|
||||
fd = mkstemp(fname);
|
||||
#ifndef WIN32
|
||||
(void)fchmod(fd, DEFFILEMODE);
|
||||
#endif
|
||||
} else {
|
||||
/*
|
||||
* Create specified file, or open the old one.
|
||||
*/
|
||||
fd = open(fname, O_CREAT | O_EXCL | O_WRONLY, DEFFILEMODE);
|
||||
if(fd == -1 && errno == EEXIST) {
|
||||
fd = open(fname, O_WRONLY, DEFFILEMODE);
|
||||
created = 0;
|
||||
}
|
||||
}
|
||||
if(fd == -1) {
|
||||
perror(fname);
|
||||
|
@ -68,6 +81,13 @@ asn1c_open_file(const char *name, const char *ext) {
|
|||
if(created) unlink(fname);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* Return the temporary file name */
|
||||
if(opt_tmpname) {
|
||||
*opt_tmpname = strdup(fname);
|
||||
assert(*opt_tmpname);
|
||||
}
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,12 @@
|
|||
|
||||
/*
|
||||
* Open the arbitrary file by its base name and extension.
|
||||
* If opt_tmpname is given, a temporary file will be created and
|
||||
* its name returned in (*opt_tmpname).
|
||||
* The (*opt_tmpname) should then be subsequently freed by free(3).
|
||||
*/
|
||||
FILE *asn1c_open_file(const char *base_part, const char *extension);
|
||||
FILE *asn1c_open_file(const char *base_part, const char *extension,
|
||||
char **opt_tmpname);
|
||||
|
||||
/*
|
||||
* Obtain base name and directory name of a path.
|
||||
|
|
|
@ -10,6 +10,7 @@ static int asn1c_dump_streams(arg_t *arg, asn1c_fdeps_t *);
|
|||
static int asn1c_print_streams(arg_t *arg);
|
||||
static int asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *);
|
||||
static int asn1c_copy_over(arg_t *arg, char *path);
|
||||
static int identical_files(const char *fname1, const char *fname2);
|
||||
|
||||
int
|
||||
asn1c_save_compiled_output(arg_t *arg, const char *datadir) {
|
||||
|
@ -41,7 +42,7 @@ asn1c_save_compiled_output(arg_t *arg, const char *datadir) {
|
|||
return 0; /* Finished */
|
||||
}
|
||||
|
||||
mkf = asn1c_open_file("Makefile.am", ".sample");
|
||||
mkf = asn1c_open_file("Makefile.am", ".sample", 0);
|
||||
if(mkf == NULL) {
|
||||
perror("Makefile.am.sample");
|
||||
return -1;
|
||||
|
@ -174,7 +175,11 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps) {
|
|||
compiler_streams_t *cs = expr->data;
|
||||
out_chunk_t *ot;
|
||||
FILE *fp_c, *fp_h;
|
||||
char *tmpname_c, *tmpname_h;
|
||||
char *name_buf;
|
||||
char *header_id;
|
||||
const char *c_retained = "";
|
||||
const char *h_retained = "";
|
||||
|
||||
if(cs == NULL) {
|
||||
fprintf(stderr, "Cannot compile %s at line %d\n",
|
||||
|
@ -182,11 +187,11 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
fp_c = asn1c_open_file(expr->Identifier, ".c");
|
||||
fp_h = asn1c_open_file(expr->Identifier, ".h");
|
||||
fp_c = asn1c_open_file(expr->Identifier, ".c", &tmpname_c);
|
||||
fp_h = asn1c_open_file(expr->Identifier, ".h", &tmpname_h);
|
||||
if(fp_c == NULL || fp_h == NULL) {
|
||||
if(fp_c) fclose(fp_c); /* lacks unlink() */
|
||||
if(fp_h) fclose(fp_h); /* lacks unlink() */
|
||||
if(fp_c) { unlink(tmpname_c); free(tmpname_c); fclose(fp_c); }
|
||||
if(fp_h) { unlink(tmpname_h); free(tmpname_h); fclose(fp_h); }
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -250,11 +255,70 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps) {
|
|||
|
||||
fclose(fp_c);
|
||||
fclose(fp_h);
|
||||
fprintf(stderr, "Compiled %s.c\n", expr->Identifier);
|
||||
fprintf(stderr, "Compiled %s.h\n", expr->Identifier);
|
||||
|
||||
name_buf = alloca(strlen(expr->Identifier) + 3);
|
||||
|
||||
sprintf(name_buf, "%s.c", expr->Identifier);
|
||||
if(identical_files(name_buf, tmpname_c)) {
|
||||
c_retained = " (contents unchanged)";
|
||||
unlink(tmpname_c);
|
||||
} else {
|
||||
if(rename(tmpname_c, name_buf)) {
|
||||
unlink(tmpname_c);
|
||||
perror(tmpname_c);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(name_buf, "%s.h", expr->Identifier);
|
||||
if(identical_files(name_buf, tmpname_h)) {
|
||||
h_retained = " (contents unchanged)";
|
||||
unlink(tmpname_h);
|
||||
} else {
|
||||
if(rename(tmpname_h, name_buf)) {
|
||||
unlink(tmpname_h);
|
||||
perror(tmpname_h);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
free(tmpname_c);
|
||||
free(tmpname_h);
|
||||
|
||||
fprintf(stderr, "Compiled %s.c%s\n",
|
||||
expr->Identifier, c_retained);
|
||||
fprintf(stderr, "Compiled %s.h%s\n",
|
||||
expr->Identifier, h_retained);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
identical_files(const char *fname1, const char *fname2) {
|
||||
char buf[2][8192];
|
||||
FILE *fp1, *fp2;
|
||||
size_t olen, nlen;
|
||||
int retval = 1; /* Files are identical */
|
||||
|
||||
fp1 = fopen(fname1, "r");
|
||||
if(!fp1) { return 0; }
|
||||
fp2 = fopen(fname2, "r");
|
||||
if(!fp2) { fclose(fp1); return 0; }
|
||||
|
||||
while((olen = fread(buf[0], 1, sizeof(buf[0]), fp1))) {
|
||||
nlen = fread(buf[1], 1, olen, fp2);
|
||||
if(nlen != olen || memcmp(buf[0], buf[1], nlen)) {
|
||||
retval = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
nlen = fread(buf[1], 1, 1, fp2);
|
||||
if(nlen) retval = 0;
|
||||
|
||||
fclose(fp1);
|
||||
fclose(fp2);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy file for real.
|
||||
*/
|
||||
|
@ -265,9 +329,12 @@ real_copy(const char *src, const char *dst) {
|
|||
size_t len;
|
||||
int retval = 0;
|
||||
|
||||
fpsrc = fopen(src, "rb");
|
||||
if(identical_files(src, dst))
|
||||
return retval; /* Success, no need to copy for real. */
|
||||
|
||||
fpsrc = fopen(src, "r");
|
||||
if(!fpsrc) { errno = EIO; return -1; }
|
||||
fpdst = fopen(src, "wb");
|
||||
fpdst = asn1c_open_file(dst, "", 0);
|
||||
if(!fpdst) { fclose(fpsrc); errno = EIO; return -1; }
|
||||
|
||||
while(!feof(fpsrc)) {
|
||||
|
|
|
@ -42,7 +42,7 @@ enum asn1c_flags {
|
|||
/*
|
||||
* Generate type_id_PR_member things identifiers of id_PR_member.
|
||||
*/
|
||||
A1C_DOUBLE_IDENTIFIERS = 0x0100,
|
||||
A1C_COMPOUND_NAMES = 0x0100,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue