diff -ruP --exclude=.svn raster/r.out.gdal/export_band.c raster/r.out.gdal.new/export_band.c
--- raster/r.out.gdal/export_band.c	2008-12-18 09:56:20.000000000 +0100
+++ raster/r.out.gdal.new/export_band.c	2008-12-16 10:41:02.000000000 +0100
@@ -25,7 +25,8 @@
 int export_band(GDALDatasetH hMEMDS, int band, const char *name,
 		const char *mapset, struct Cell_head *cellhead,
 		RASTER_MAP_TYPE maptype, double nodataval,
-		const char *nodatakey, int suppress_main_colortable)
+		const char *nodatakey, int suppress_main_colortable,
+		int default_nodataval)
 {
 
     struct Colors sGrassColors;
@@ -63,9 +64,6 @@
 	G_get_fp_range_min_max(&sRange, &dfCellMin, &dfCellMax);
     }
 
-    /* TODO: if data range exceeds export TYPE range exit with an error.
-       Otherwise the module doesn't know what to write for those values */
-
     /* suppress useless warnings */
     CPLPushErrorHandler(CPLQuietErrorHandler);
     GDALSetRasterColorInterpretation(hBand, GPI_RGB);
@@ -169,7 +167,8 @@
 	if (!suppress_main_colortable) {
 	    hCT = GDALCreateColorTable(GPI_RGB);
 	    GDALSetMetadataItem(hBand, "COLOR_TABLE_RULES_COUNT", "0", NULL);
-	    GDALSetRasterColorTable(hBand, hCT);
+	    /* this is not a good idea: the display will be all black */
+	    /* GDALSetRasterColorTable(hBand, hCT); */
 	}
     }
 
@@ -286,7 +285,7 @@
 	}
     }
 
-    if (n_nulls > 0) {		/* TODO: && nodata_param NOT specified */
+    if (n_nulls > 0 && default_nodataval) {
 	if (maptype == CELL_TYPE)
 	    G_warning(_("Input raster map contains cells with NULL-value (no-data). "
 		       "The value %d was used to represent no-data values in the input map. "
diff -ruP --exclude=.svn raster/r.out.gdal/local_proto.h raster/r.out.gdal.new/local_proto.h
--- raster/r.out.gdal/local_proto.h	2008-11-25 02:30:39.000000000 +0100
+++ raster/r.out.gdal.new/local_proto.h	2008-12-16 09:54:30.000000000 +0100
@@ -1,9 +1,7 @@
 #ifndef __LOCAL_PROTO_H__
 #define __LOCAL_PROTO_H__
 
-
-#define GRASS_MAX_COLORS 100000	/* what is the right value? UInt16 -> 65535 ? */
-/* TODO: better- set from lesser of above and TYPE limits listed below */
+#include "gdal.h"
 
 /* range limits */
 /*
@@ -18,38 +16,50 @@
   Float64, CFloat64          -1.79E308         1.79E308
 */
 
-/* TODO: for data export range checks and nodata value check
+/* copied from limits.h */
 #define TYPE_BYTE_MIN		0
 #define TYPE_BYTE_MAX		255
-#define TYPE_INT16_MIN		-32768
+#define TYPE_INT16_MIN		(-32768)
 #define TYPE_INT16_MAX		32767
 #define TYPE_UINT16_MIN		0
 #define TYPE_UINT16_MAX		65535
 #define TYPE_UINT32_MIN		0
-#define TYPE_UINT32_MAX		4294967295     // better to use (double)(unsigned int)0xFFFFFFFFu  ?
-#define TYPE_INT32_MIN		-2147483648
+#define TYPE_UINT32_MAX		4294967295U
+#define TYPE_INT32_MIN		-TYPE_INT32_MAX - 1
 #define TYPE_INT32_MAX		2147483647
-#define TYPE_FLOAT32_MIN	-3.4E38f
-#define TYPE_FLOAT32_MAX	3.4E38f
+
+/* new systems: FLT_MAX, DBL_MAX, old systems: MAXFLOAT, MAXDOUBLE, fallback: 3.4E38 and 1.79E308f */
+#ifdef FLT_MAX
+#define TYPE_FLOAT32_MIN	-FLT_MAX
+#define TYPE_FLOAT32_MAX	FLT_MAX
+#elif defined(MAX_FLOAT)
+#define TYPE_FLOAT32_MIN	-MAXFLOAT
+#define TYPE_FLOAT32_MAX	MAXFLOAT
+#else
+#define TYPE_FLOAT32_MIN	-3.4E38
+#define TYPE_FLOAT32_MAX	3.4E38
+#endif
+
+#ifdef DBL_MAX
+#define TYPE_FLOAT64_MIN	-DBL_MAX
+#define TYPE_FLOAT64_MAX	DBL_MAX
+#elif defined(MAXDOUBLE)
+#define TYPE_FLOAT64_MIN	-MAXDOUBLE
+#define TYPE_FLOAT64_MAX	MAXDOUBLE
+#else
 #define TYPE_FLOAT64_MIN	-1.79E308f
 #define TYPE_FLOAT64_MAX	1.79E308f
+#endif
 
- better to not define Ctypes here, rather in the code use
-  if( type == F16 || type== CF16 ) 
-#define TYPE_CINT16_MIN		TYPE_INT16_MIN
-#define TYPE_CINT16_MAX		TYPE_INT16_MAX
-#define TYPE_CINT32_MIN		TYPE_INT32_MIN
-#define TYPE_CINT32_MAX		TYPE_INT32_MAX
-#define TYPE_CFLOAT32_MIN	TYPE_FLOAT32_MIN
-#define TYPE_CFLOAT32_MAX	TYPE_FLOAT32_MAX
-#define TYPE_CFLOAT64_MIN	TYPE_FLOAT64_MIN
-#define TYPE_CFLOAT64_MAX	TYPE_FLOAT64_MAX
-*/
+#define GRASS_MAX_COLORS TYPE_UINT16_MAX
 
+/* main.c */
+int range_check(double, double, GDALDataType, char *);
+int nullvalue_check(double, GDALDataType);
 
 /* export_band.c */
 int export_band(GDALDatasetH, int, const char *, const char *,
 		struct Cell_head *, RASTER_MAP_TYPE, double,
-		const char *, int);
+		const char *, int, int);
 
 #endif /* __LOCAL_PROTO_H__ */
diff -ruP --exclude=.svn raster/r.out.gdal/main.c raster/r.out.gdal.new/main.c
--- raster/r.out.gdal/main.c	2008-12-18 09:56:20.000000000 +0100
+++ raster/r.out.gdal.new/main.c	2008-12-16 10:39:30.000000000 +0100
@@ -30,7 +30,6 @@
 #include <grass/dbmi.h>
 
 #include "cpl_string.h"
-#include "gdal.h"
 #include "local_proto.h"
 
 
@@ -132,7 +131,7 @@
 
     flag_c = G_define_flag();
     flag_c->key = 'c';
-    flag_c->label = _("Do not export long colortable");
+    flag_c->label = _("Do not write GDAL standard colortable");
     flag_c->description = _("Only applicable to Byte or UInt16 data types.");
 
     input = G_define_standard_option(G_OPT_R_INPUT);
@@ -274,69 +273,71 @@
     GDALDataType datatype = GDT_Unknown;
     double nodataval;
 
+    maptype = CELL_TYPE;
+
     if (type->answer) {
 	/* reduce number of strcmps ... */
 	if (type->answer[0] == 'B') {
 	    datatype = GDT_Byte;
 	    maptype = CELL_TYPE;
-	    nodataval = (double)(unsigned char)0xFFu;
+	    nodataval = TYPE_BYTE_MIN;
 	}
 	else if (type->answer[0] == 'I') {
 	    if (strcmp(type->answer, "Int16") == 0) {
 		datatype = GDT_Int16;
 		maptype = CELL_TYPE;
-		nodataval = (double)(short)0x8000;
+		nodataval = TYPE_INT16_MIN;
 	    }
 	    else if (strcmp(type->answer, "Int32") == 0) {
 		datatype = GDT_Int32;
 		maptype = CELL_TYPE;
-		nodataval = (double)(int)0x80000000;
+		nodataval = TYPE_INT32_MIN;
 	    }
 	}
 	else if (type->answer[0] == 'U') {
 	    if (strcmp(type->answer, "UInt16") == 0) {
 		datatype = GDT_UInt16;
 		maptype = CELL_TYPE;
-		nodataval = (double)(unsigned short)0xFFFFu;
+		nodataval = TYPE_UINT16_MIN;
 	    }
 	    else if (strcmp(type->answer, "UInt32") == 0) {
 		datatype = GDT_UInt32;
 		maptype = DCELL_TYPE;
-		nodataval = (double)(unsigned int)0xFFFFFFFFu;
+		nodataval = TYPE_UINT32_MIN;
 	    }
 	}
 	else if (type->answer[0] == 'F') {
 	    if (strcmp(type->answer, "Float32") == 0) {
 		datatype = GDT_Float32;
 		maptype = FCELL_TYPE;
-		nodataval = -1E37f;
+		nodataval = TYPE_FLOAT32_MIN;
 	    }
 	    else if (strcmp(type->answer, "Float64") == 0) {
 		datatype = GDT_Float64;
 		maptype = DCELL_TYPE;
-		nodataval = -1E37f;
+		nodataval = TYPE_FLOAT64_MIN;
 	    }
 	}
 	else if (type->answer[0] == 'C') {
 	    if (strcmp(type->answer, "CInt16") == 0) {
 		datatype = GDT_CInt16;
 		maptype = CELL_TYPE;
-		nodataval = (double)(short)0x8000;
+		nodataval = TYPE_INT16_MIN;
 	    }
 	    else if (strcmp(type->answer, "CInt32") == 0) {
 		datatype = GDT_CInt32;
 		maptype = CELL_TYPE;
-		nodataval = (double)(int)0x80000000;
+		nodataval = TYPE_INT32_MIN;
 	    }
 	    else if (strcmp(type->answer, "CFloat32") == 0) {
 		datatype = GDT_CFloat32;
 		maptype = FCELL_TYPE;
-		nodataval = -1E37f;
+		nodataval = TYPE_FLOAT32_MIN;
 	    }
 	    else if (strcmp(type->answer, "CFloat64") == 0) {
 		datatype = GDT_CFloat64;
 		maptype = DCELL_TYPE;
-		nodataval = -1E37f;
+		nodataval = TYPE_FLOAT64_MIN;
 	    }
 	}
     }
@@ -357,41 +358,42 @@
 	maptype = G_raster_map_type(ref.file[0].name, ref.file[0].mapset);
 	if (maptype == FCELL_TYPE) {
 	    datatype = GDT_Float32;
-	    nodataval = -1E37f;
+	    nodataval = TYPE_FLOAT32_MIN;;
 	}
 	else if (maptype == DCELL_TYPE) {
 	    datatype = GDT_Float64;
-	    nodataval = -1E37f;
+	    nodataval = TYPE_FLOAT64_MIN;;
 	}
 	else {
 	    /* Special tricks for GeoTIFF color table support and such */
 	    if (dfCellMin >= 0 && dfCellMax < 256) {
 		datatype = GDT_Byte;
-		nodataval = (double)(unsigned char)0xFFu;
+		nodataval = TYPE_BYTE_MIN;
 	    }
 	    else {
 		if (dfCellMin >= 0 && dfCellMax < 65536) {
 		    datatype = GDT_UInt16;
-		    nodataval = (double)(short)0x8000;
+		    nodataval = TYPE_UINT16_MIN;
 		}
 		else {
 		    datatype = GDT_Int32;	/* need to fine tune this more? */
-		    nodataval = (double)(int)0x80000000;
+		    nodataval = TYPE_INT32_MIN;;
 		}
 	    }
 	}
     }
 
     /* force nodata-value if needed */
+    int default_nodataval = 1;
+
     if (nodataopt->answer) {
 	nodataval = atof(nodataopt->answer);
+	default_nodataval = 0;
+	/* check nodataval here, not in export_band, because it is specified only once */
+	if (nullvalue_check(nodataval, datatype))
+	    G_fatal_error("Raster export aborted.");
     }
 
-    /* TODO:
-       if( nodata_used && nodataval is out_of_type_range )
-       G_fatal_error(_("No-data value out of range for type %s"), type->answer);
-     */
-
     G_debug(3, "Input map datatype=%s\n",
 	    (maptype == CELL_TYPE ? "CELL" :
 	     (maptype == DCELL_TYPE ? "DCELL" :
@@ -469,10 +471,26 @@
 						     ref.file[band].mapset),
 			      band + 1);
 	}
+	/* do range check here because we don't have GDALDataType in export_band */
+	if (G_read_fp_range
+	    (ref.file[band].name, ref.file[band].mapset, &sRange) == -1) {
+	    bHaveMinMax = FALSE;
+	}
+	else {
+	    bHaveMinMax = TRUE;
+	    G_get_fp_range_min_max(&sRange, &dfCellMin, &dfCellMax);
+	}
+	G_debug(3, "Range: min: %f, max: %f", dfCellMin, dfCellMax);
+	if (bHaveMinMax == TRUE) {
+	    if (range_check
+		(dfCellMin, dfCellMax, datatype, ref.file[band].name))
+		G_fatal_error("Raster export aborted");
+	}
+
 	if (export_band
 	    (hCurrDS, band + 1, ref.file[band].name, ref.file[band].mapset,
-	     &cellhead, maptype, nodataval, nodataopt->key,
-	     flag_c->answer) < 0)
+	     &cellhead, maptype, nodataval, nodataopt->key, flag_c->answer,
+	     default_nodataval) < 0)
 	    G_warning(_("Unable to export raster map <%s>"),
 		      ref.file[band].name);
     }
@@ -497,3 +515,202 @@
     G_done_msg(" ");
     exit(EXIT_SUCCESS);
 }
+
+
+int range_check(double min, double max, GDALDataType datatype, char *name)
+{
+    /* what accuracy to use to print min max for FLOAT32 and FLOAT64? %g enough? */
+
+    switch (datatype) {
+    case GDT_Byte:
+	if (min < TYPE_BYTE_MIN || max > TYPE_BYTE_MAX) {
+	    G_warning(_("Selected GDAL datatype does not cover data range."));
+	    G_warning(_("GDAL datatype: %s, range: %d - %d"),
+		      GDALGetDataTypeName(datatype), TYPE_BYTE_MIN,
+		      TYPE_BYTE_MAX);
+	    G_warning(_("Raster map <%s> range: %g - %g"), name, min, max);
+	    return 1;
+	}
+	else
+	    return 0;
+
+    case GDT_UInt16:
+	if (min < TYPE_UINT16_MIN || max > TYPE_UINT16_MAX) {
+	    G_warning(_("Selected GDAL datatype does not cover data range."));
+	    G_warning(_("GDAL datatype: %s, range: %d - %d"),
+		      GDALGetDataTypeName(datatype), TYPE_UINT16_MIN,
+		      TYPE_UINT16_MAX);
+	    G_warning(_("Raster map <%s> range: %g - %g"), name, min, max);
+	    return 1;
+	}
+	else
+	    return 0;
+
+    case GDT_Int16:
+    case GDT_CInt16:
+	if (min < TYPE_INT16_MIN || max > TYPE_INT16_MAX) {
+	    G_warning(_("Selected GDAL datatype does not cover data range."));
+	    G_warning(_("GDAL datatype: %s, range: %d - %d"),
+		      GDALGetDataTypeName(datatype), TYPE_INT16_MIN,
+		      TYPE_INT16_MAX);
+	    G_warning(_("Raster map <%s> range: %g - %g"), name, min, max);
+	    return 1;
+	}
+	else
+	    return 0;
+
+    case GDT_Int32:
+    case GDT_CInt32:
+	if (min < TYPE_INT32_MIN || max > TYPE_INT32_MAX) {
+	    G_warning(_("Selected GDAL datatype does not cover data range."));
+	    G_warning(_("GDAL datatype: %s, range: %d - %d"),
+		      GDALGetDataTypeName(datatype), TYPE_INT32_MIN,
+		      TYPE_INT32_MAX);
+	    G_warning(_("Raster map <%s> range: %g - %g"), name, min, max);
+	    return 1;
+	}
+	else
+	    return 0;
+
+    case GDT_UInt32:
+	if (min < TYPE_UINT32_MIN || max > TYPE_UINT32_MAX) {
+	    G_warning(_("Selected GDAL datatype does not cover data range."));
+	    G_warning(_("GDAL datatype: %s, range: %u - %u"),
+		      GDALGetDataTypeName(datatype), TYPE_UINT32_MIN,
+		      TYPE_UINT32_MAX);
+	    G_warning(_("Raster map <%s> range: %g - %g"), name, min, max);
+	    return 1;
+	}
+	else
+	    return 0;
+
+    case GDT_Float32:
+    case GDT_CFloat32:
+	if (min < TYPE_FLOAT32_MIN || max > TYPE_FLOAT32_MAX) {
+	    G_warning(_("Selected GDAL datatype does not cover data range."));
+	    G_warning(_("GDAL datatype: %s, range: %g - %g"),
+		      GDALGetDataTypeName(datatype), TYPE_FLOAT32_MIN,
+		      TYPE_FLOAT32_MAX);
+	    G_warning(_("Raster map <%s> range: %g - %g"), name, min, max);
+	    return 1;
+	}
+	else
+	    return 0;
+
+    case GDT_Float64:
+    case GDT_CFloat64:
+	/* not possible because DCELL is FLOAT64, not 128bit floating point, but anyway... */
+	if (min < TYPE_FLOAT64_MIN || max > TYPE_FLOAT64_MAX) {
+	    G_warning(_("Selected GDAL datatype does not cover data range."));
+	    G_warning(_("GDAL datatype: %s, range: %g - %g"),
+		      GDALGetDataTypeName(datatype), TYPE_FLOAT64_MIN,
+		      TYPE_FLOAT64_MAX);
+	    G_warning(_("Raster map <%s> range: %g - %g"), name, min, max);
+	    return 1;
+	}
+	else
+	    return 0;
+
+    default:
+	return 0;
+    }
+}
+
+int nullvalue_check(double nodataval, GDALDataType datatype)
+{
+    /* what accuracy to use to print nodataval for FLOAT32 and FLOAT64? %g enough? */
+
+    switch (datatype) {
+    case GDT_Byte:
+	if (nodataval < TYPE_BYTE_MIN || nodataval > TYPE_BYTE_MAX) {
+	    G_warning(_("Specified nodata value %g is not covered by range of selected GDAL datatype."),
+		      nodataval);
+	    G_warning(_("GDAL datatype: %s, range: %d - %d"),
+		      GDALGetDataTypeName(datatype), TYPE_BYTE_MIN,
+		      TYPE_BYTE_MAX);
+	    return 1;
+	}
+	else
+	    return 0;
+
+    case GDT_UInt16:
+	if (nodataval < TYPE_UINT16_MIN || nodataval > TYPE_UINT16_MAX) {
+	    G_warning(_("Specified nodata value %g is not covered by range of selected GDAL datatype."),
+		      nodataval);
+	    G_warning(_("GDAL datatype: %s, range: %d - %d"),
+		      GDALGetDataTypeName(datatype), TYPE_UINT16_MIN,
+		      TYPE_UINT16_MAX);
+	    return 1;
+	}
+	else
+	    return 0;
+
+    case GDT_Int16:
+    case GDT_CInt16:
+	if (nodataval < TYPE_INT16_MIN || nodataval > TYPE_INT16_MAX) {
+	    G_warning(_("Specified nodata value %g is not covered by range of selected GDAL datatype."),
+		      nodataval);
+	    G_warning(_("GDAL datatype: %s, range: %d - %d"),
+		      GDALGetDataTypeName(datatype), TYPE_INT16_MIN,
+		      TYPE_INT16_MAX);
+	    return 1;
+	}
+	else
+	    return 0;
+
+    case GDT_Int32:
+    case GDT_CInt32:
+	if (nodataval < TYPE_INT32_MIN || nodataval > TYPE_INT32_MAX) {
+	    G_warning(_("Specified nodata value %g is not covered by range of selected GDAL datatype."),
+		      nodataval);
+	    G_warning(_("GDAL datatype: %s, range: %d - %d"),
+		      GDALGetDataTypeName(datatype), TYPE_INT32_MIN,
+		      TYPE_INT32_MAX);
+	    return 1;
+	}
+	else
+	    return 0;
+
+    case GDT_UInt32:
+	if (nodataval < TYPE_UINT32_MIN || nodataval > TYPE_UINT32_MAX) {
+	    G_warning(_("Specified nodata value %g is not covered by range of selected GDAL datatype."),
+		      nodataval);
+	    G_warning(_("GDAL datatype: %s, range: %u - %u"),
+		      GDALGetDataTypeName(datatype), TYPE_UINT32_MIN,
+		      TYPE_UINT32_MAX);
+	    return 1;
+	}
+	else
+	    return 0;
+
+    case GDT_Float32:
+    case GDT_CFloat32:
+	if (nodataval < TYPE_FLOAT32_MIN || nodataval > TYPE_FLOAT32_MAX) {
+	    G_warning(_("Specified nodata value %g is not covered by range of selected GDAL datatype."),
+		      nodataval);
+	    G_warning(_("GDAL datatype: %s, range: %g - %g"),
+		      GDALGetDataTypeName(datatype), TYPE_FLOAT32_MIN,
+		      TYPE_FLOAT32_MAX);
+	    return 1;
+	}
+	else
+	    return 0;
+
+    case GDT_Float64:
+    case GDT_CFloat64:
+	/* not possible because double is FLOAT64, not 128bit floating point */
+	if (nodataval < TYPE_FLOAT64_MIN || nodataval > TYPE_FLOAT64_MAX) {
+	    G_warning(_("Specified nodata value %g is not covered by range of selected GDAL datatype."),
+		      nodataval);
+	    G_warning(_("GDAL datatype: %s, range: %g - %g"),
+		      GDALGetDataTypeName(datatype), TYPE_FLOAT64_MIN,
+		      TYPE_FLOAT64_MAX);
+	    return 1;
+	}
+	else
+	    return 0;
+
+    default:
+	return 0;
+    }
+}

