/ Check-in [20c995d3]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Enhance the edit() function so that it converts text from \r\n back into \n only if the original unedited copy contained no \r\n values.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 20c995d3f0f4de5410962172cb59da0f25edf0c62e199420186cc59ea874e981
User & Date: drh 2018-08-06 02:08:53
Context
2018-08-08
20:46
Minor style improvements. check-in: 60bbca2b user: mistachkin tags: trunk
2018-08-06
17:12
Allow sqlite3_snapshot_open() to be called to change the snapshot after a read transaction is already open on database. Closed-Leaf check-in: 051ac015 user: dan tags: exp-snapshot-open
02:08
Enhance the edit() function so that it converts text from \r\n back into \n only if the original unedited copy contained no \r\n values. check-in: 20c995d3 user: drh tags: trunk
01:39
Add the --info option to the fuzzcheck test utility. check-in: 1caaaaa7 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/shell.c.in.

  1180   1180   ){
  1181   1181     const char *zEditor;
  1182   1182     char *zTempFile = 0;
  1183   1183     sqlite3 *db;
  1184   1184     char *zCmd = 0;
  1185   1185     int bBin;
  1186   1186     int rc;
         1187  +  int hasCRNL = 0;
  1187   1188     FILE *f = 0;
  1188   1189     sqlite3_int64 sz;
  1189   1190     sqlite3_int64 x;
  1190   1191     unsigned char *p = 0;
  1191   1192   
  1192   1193     if( argc==2 ){
  1193   1194       zEditor = (const char*)sqlite3_value_text(argv[1]);
................................................................................
  1211   1212       zTempFile = sqlite3_mprintf("temp%llx", r);
  1212   1213       if( zTempFile==0 ){
  1213   1214         sqlite3_result_error_nomem(context);
  1214   1215         return;
  1215   1216       }
  1216   1217     }
  1217   1218     bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB;
         1219  +  /* When writing the file to be edited, do \n to \r\n conversions on systems
         1220  +  ** that want \r\n line endings */
  1218   1221     f = fopen(zTempFile, bBin ? "wb" : "w");
  1219   1222     if( f==0 ){
  1220   1223       sqlite3_result_error(context, "edit() cannot open temp file", -1);
  1221   1224       goto edit_func_end;
  1222   1225     }
  1223   1226     sz = sqlite3_value_bytes(argv[0]);
  1224   1227     if( bBin ){
  1225   1228       x = fwrite(sqlite3_value_blob(argv[0]), 1, sz, f);
  1226   1229     }else{
         1230  +    const char *z = (const char*)sqlite3_value_text(argv[0]);
         1231  +    /* Remember whether or not the value originally contained \r\n */
         1232  +    if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1;
  1227   1233       x = fwrite(sqlite3_value_text(argv[0]), 1, sz, f);
  1228   1234     }
  1229   1235     fclose(f);
  1230   1236     f = 0;
  1231   1237     if( x!=sz ){
  1232   1238       sqlite3_result_error(context, "edit() could not write the whole file", -1);
  1233   1239       goto edit_func_end;
................................................................................
  1239   1245     }
  1240   1246     rc = system(zCmd);
  1241   1247     sqlite3_free(zCmd);
  1242   1248     if( rc ){
  1243   1249       sqlite3_result_error(context, "EDITOR returned non-zero", -1);
  1244   1250       goto edit_func_end;
  1245   1251     }
  1246         -  f = fopen(zTempFile, bBin ? "rb" : "r");
         1252  +  f = fopen(zTempFile, "rb");
  1247   1253     if( f==0 ){
  1248   1254       sqlite3_result_error(context,
  1249   1255         "edit() cannot reopen temp file after edit", -1);
  1250   1256       goto edit_func_end;
  1251   1257     }
  1252   1258     fseek(f, 0, SEEK_END);
  1253   1259     sz = ftell(f);
  1254   1260     rewind(f);
  1255   1261     p = sqlite3_malloc64( sz+(bBin==0) );
  1256   1262     if( p==0 ){
  1257   1263       sqlite3_result_error_nomem(context);
  1258   1264       goto edit_func_end;
  1259   1265     }
  1260         -  if( bBin ){
  1261         -    x = fread(p, 1, sz, f);
  1262         -  }else{
  1263         -    x = fread(p, 1, sz, f);
  1264         -    p[sz] = 0;
  1265         -  }
         1266  +  x = fread(p, 1, sz, f);
  1266   1267     fclose(f);
  1267   1268     f = 0;
  1268   1269     if( x!=sz ){
  1269   1270       sqlite3_result_error(context, "could not read back the whole file", -1);
  1270   1271       goto edit_func_end;
  1271   1272     }
  1272   1273     if( bBin ){
  1273   1274       sqlite3_result_blob64(context, p, sz, sqlite3_free);
  1274   1275     }else{
         1276  +    int i, j;
         1277  +    if( hasCRNL ){
         1278  +      /* If the original contains \r\n then do no conversions back to \n */
         1279  +      j = sz;
         1280  +    }else{
         1281  +      /* If the file did not originally contain \r\n then convert any new
         1282  +      ** \r\n back into \n */
         1283  +      for(i=j=0; i<sz; i++){
         1284  +        if( p[i]=='\r' && p[i+1]=='\n' ) i++;
         1285  +        p[j++] = p[i];
         1286  +      }
         1287  +      sz = j;
         1288  +      p[sz] = 0;
         1289  +    } 
  1275   1290       sqlite3_result_text64(context, (const char*)p, sz,
  1276   1291                             sqlite3_free, SQLITE_UTF8);
  1277   1292     }
  1278   1293     p = 0;
  1279   1294   
  1280   1295   edit_func_end:
  1281   1296     if( f ) fclose(f);