.\" $Header: /upc/share/CVS/netcdf-3/ncgen/ncgen.1,v 1.10 2010/04/29 16:38:55 dmh Exp $ .TH NCGEN 1 "$Date: 2010/04/29 16:38:55 $" "Printed: \n(yr-\n(mo-\n(dy" "UNIDATA UTILITIES" .SH "نام (NAME)" ncgen \- تولید پرونده‌های netCDF-3، netCDF-4 یا برنامه C از روی پرونده CDL .SH "خلاصه دستور (SYNOPSIS)" .HP ncgen .nh \%[\-\fIformat_code\fP] \%[\-1|3|4|5|6|7] \%[\-b] \%[\-c] \%[\-d] \%[\-D \fIdebuglevel\fP] \%[\-f] \%[\-h] \%[\-H] \%[\-k \fIformat_name\fP] \%[\-l \fIb|c|f77|java\fP] \%[\-L \fIloglevel\fP] \%[\-M \fIname\fP] \%[\-n] \%[\-N \fIdatasetname\fP] \%[\-o \fInetcdf_filename\fP] \%[\-P] .\%[\-W \fImaxwholevarsize\fP] \%[\-x] .hy .ft .SH "توضیحات (DESCRIPTION)" دستور \fBncgen\fP یک پرونده دودویی ‎.nc با قالب netCDF-3 (یعنی کلاسیک)، یک پرونده دودویی ‎.nc با قالب netCDF-4 (یعنی پیشرفته/ارتقایافته)، یا پرونده‌ای به یکی از زبان‌های برنامه‌نویسی مبدأ تولید می‌کند که در هنگام اجرا، پرونده دودویی ‎.nc متناظر را خواهد ساخت. ورودی \fBncgen\fP توصیفی از یک پرونده netCDF به زبان ساده‌ای موسوم به CDL (کوتاه‌نوشت network Common Data form Language) است که در ادامه شرح داده شده است. در صورتی که هیچ پرونده ورودی تعیین نشود، ورودی از ورودی استاندارد خوانده می‌شود. اگر در هنگام فراخوانی \fBncgen\fP هیچ گزینه‌ای مشخص نشود، این ابزار صرفاً نحو (syntax) پرونده CDL ورودی را بررسی کرده و برای هرگونه مغایرت با نحو CDL پیام خطا صادر می‌کند. گزینه‌های دیگر می‌توانند مثلاً برای ایجاد پرونده netCDF متناظر یا تولید یک برنامه به زبان C که از رابط C نت‌سی‌دی‌اف برای ساخت پرونده netCDF استفاده می‌کند، به‌کار روند. .LP توجه داشته باشید که این نسخه از ncgen در ابتدا ncgen4 نامیده می‌شد. برنامه قدیمی‌تر ncgen به ncgen3 تغییر نام یافته است. .LP می‌توان از \fBncgen\fP همراه با برنامه مکمل آن یعنی \fBncdump\fP برای انجام برخی عملیات ساده روی پرونده‌های netCDF استفاده کرد. برای مثال، جهت تغییر نام یک بُعد در یک پرونده netCDF، با استفاده از \fBncdump\fP نسخه CDL پرونده netCDF را دریافت کنید، پرونده CDL را برای تغییر نام ابعاد ویرایش نمایید و با استفاده از \fBncgen\fP پرونده netCDF متناظر را از روی پرونده ویرایش‌شده CDL تولید کنید. .SH "گزینه‌ها (OPTIONS)" .IP "\fB-1|3|4|5|6|7\fP" روش جایگزین برای مشخص کردن قالب. .RS .RS .IP "3 => قالب کلاسیک netcdf" .IP "4 => قالب netCDF-4 (مدل داده پیشرفته)" .IP "5 => قالب netcdf 5" .IP "6 => قالب 64-بیتی netCDF" .IP "7 => قالب مدل کلاسیک netCDF-4 (3+4 == 7)" .RE .RE گزینه \fB-k\fP را ببینید. .IP "\fB-b\fP" ایجاد یک پرونده netCDF (دودویی). اگر گزینه \fB-o\fP ارائه نشود، یک نام پرونده پیش‌فرض از روی نام پایه (basename) پرونده CDL ساخته می‌شود و هر پسوندی با پسوند «‎.nc» جایگزین می‌گردد. اگر پرونده‌ای با این نام از قبل وجود داشته باشد، رونویسی خواهد شد. .IP "\fB-c\fP" تولید کد منبع .B C که یک پرونده netCDF مطابق با مشخصات netCDF ایجاد می‌کند. کد منبع C در خروجی استاندارد نوشته می‌شود؛ معادل با \-lc است. .IP "\fB-d\fP" همانند \fB-D1\fP. .IP "\fB-D\fP \fRdebuglevel\fP" تنظیم سطح خروجی اشکال‌زدایی (debug). .IP "\fB-f\fP" تولید کد منبع .B FORTRAN 77 که یک پرونده netCDF مطابق با مشخصات netCDF ایجاد می‌کند. کد منبع در خروجی استاندارد نوشته می‌شود؛ معادل با \-lf77 است. .IP "\fB-h\fP" نمایش اطلاعات راهنما. .IP "\fB-H\fP" تنها چاپ سرایند (header)؛ بخش داده (\fIdata\fP) نادیده گرفته می‌شود. .IP "\fB-k \fIformat_name\fP" .IP "\fB-\fIformat_code\fP" گزینه \-k قالب پرونده‌ای را که باید ایجاد شود و متعاقباً مدل داده پذیرفته‌شده توسط ncgen (یعنی netcdf-3 (کلاسیک) در برابر netcdf-4 و netcdf-5) را تعیین می‌کند. به‌عنوان یک میانبر، یک شناسه عددی \fIformat_code\fP می‌تواند به‌جای آن تعیین شود. مقادیر ممکن برای \fIformat_name\fP در گزینه \-k عبارتند از: .RS .RS .IP "'classic' یا 'nc3' => قالب کلاسیک netCDF" .IP "'64-bit offset' یا 'nc6' => قالب 64-بیتی netCDF" .IP "'64-bit data' یا 'nc5' => قالب netCDF-5 (داده‌های 64-بیتی)" .IP "'netCDF-4' یا 'nc4' => قالب netCDF-4 (مدل داده پیشرفته)" .IP "'netCDF-4 classic model' یا 'nc7' => قالب مدل کلاسیک netCDF-4" .RE .RE شناسه‌های عددی پذیرفته‌شده برای \fIformat_code\fP، که میانبرهایی برای نام قالب‌ها هستند، عبارتند از: .RS .RS .IP "3 => قالب کلاسیک netcdf" .IP "5 => قالب netcdf 5" .IP "6 => قالب 64-بیتی netCDF" .IP "4 => قالب netCDF-4 (مدل داده پیشرفته)" .IP "7 => قالب مدل کلاسیک netCDF-4" .RE .RE کد عددی «7» به این دلیل استفاده می‌شود که «7=3+4» است؛ یادآوری برای قالبی که از مدل داده netCDF-3 برای سازگاری و از قالب ذخیره‌سازی netCDF-4 برای کارایی استفاده می‌کند. اعتبار استفاده از این کدهای عددی به‌جای شماره قالب‌های قدیمی و گیج‌کننده متعلق به NCO است. .LP توجه: شماره قالب‌های نسخه قدیمی یعنی '1'، '2'، '3'، '4' که به‌ترتیب معادل نام قالب‌های 'nc3'، 'nc6'، 'nc4' یا 'nc7' هستند، به دلیل اشتباه گرفته شدن آسان شماره قالب با نام قالب، اگرچه هنوز پذیرفته می‌شوند اما منسوخ (deprecated) شده‌اند. نام‌های مستعار قدیمی گوناگون نیز پذیرفته می‌شوند اما منسوخ شده‌اند، مانند 'hdf5'، 'enhanced-nc3' و غیره. همچنین توجه داشته باشید که گزینه \-v به جهت سازگاری با گذشته، هم‌معنی با \-k پذیرفته می‌شود. .IP "\fB-l\fP \fRb|c|f77|java\fP" گزینه \-l زبان خروجی را مشخص می‌کند که هنگام تولید کد منبع برای ایجاد یا تعریف پرونده netCDF مطابق با مشخصات netCDF استفاده می‌شود. خروجی در خروجی استاندارد نوشته می‌شود. زبان‌های پشتیبانی‌شده در حال حاضر دارای شناسه‌های زیر هستند: .RS .RS .IP "c|C' => خروجی به زبان C." .IP "f77|fortran77' => خروجی به زبان FORTRAN 77" ؛ توجه داشته باشید که در حال حاضر تنها مدل کلاسیک پشتیبانی می‌شود. .IP "j|java' => خروجی آزمایشی به زبان Java" ؛ رابط جاوا موجود در Unidata را هدف قرار می‌دهد، بدین معنی که فقط مدل کلاسیک پشتیبانی می‌شود. .RE .RE .SH "انتخاب قالب خروجی (Choosing the output format)" انتخاب قالب خروجی توسط سه عامل تعیین می‌شود: .IP "\fBگزینه -k\fP" .IP "\fBصفت _Format (پایین‌تر را ببینید).\fP" .IP "\fBحضور ساختارهای CDF-5 (داده‌های 64-بیتی) یا netcdf-4 در CDL ورودی.\fP" اصطلاح «ساختارهای netCDF-4» به معنی ساختارهای برگرفته از مدل داده پیشرفته است، نه فقط صفت‌های ویژه مربوط به کارایی مانند _ChunkSizes، _DeflateLevel، _Endianness و غیره. اصطلاح «ساختارهای CDF-5» به معنای انواع عدد صحیح بدون علامت توسعه‌یافته است که در مدل داده 64-بیتی مجاز هستند. .LP توجه داشته باشید که اگر در ورودی تنها یک نوع بدون علامت دیده شود، ابهامی میان حالت netCDF-4 و حالت CDF-5 ایجاد می‌شود. .LP قواعد به ترتیب اعمال به شرح زیر هستند: .IP "\fB1.\fP" اگر خروجی فرترن یا جاوا تعیین شده باشد، مقدار 1 (مدل کلاسیک) برای گزینه \-k استفاده خواهد شد. تداخل با کاربرد ساختارهای پیشرفته در CDL یک خطا گزارش خواهد کرد. .IP "\fB2.\fP" اگر هم گزینه \-k و هم صفت _Format مشخص شده باشند، صفت _Format نادیده گرفته خواهد شد. اگر هیچ گزینه \-k مشخص نشده باشد و یک مقدار صفت _Format تعیین شده باشد، آنگاه مقدار گزینه \-k برابر با مقدار صفت _Format قرار خواهد گرفت. در غیر این صورت گزینه \-k تعریف‌نشده باقی می‌ماند. .IP "\fB3.\fP" اگر گزینه \-k تعریف شده باشد و با CDL سازگار باشد، ncgen پرونده‌ای را در قالب خواسته‌شده ایجاد می‌کند؛ در غیر این صورت یک خطا گزارش می‌شود. .IP "\fB4.\fP" اگر گزینه \-k تعریف‌نشده باشد و در CDL فقط ساختارهای CDF-5 وجود داشته باشد، مقدار 5 (مدل داده 64-بیتی) برای گزینه \-k استفاده خواهد شد. اگر ساختارهای حقیقی netCDF-4 در CDL وجود داشته باشند، مقدار 3 (مدل پیشرفته) برای گزینه \-k استفاده خواهد شد. .IP "\fB5.\fP" اگر صفت‌های ویژه مربوط به کارایی در CDL مشخص شده باشند، مقدار 4 (مدل کلاسیک netCDF-4) برای گزینه \-k استفاده خواهد شد. .IP "\fB6.\fP" در غیر این صورت، ncgen مقدار گزینه \-k را برابر با 1 (مدل کلاسیک) قرار می‌دهد. .RE .IP "\fB-L\fP \fRloglevel\fP" تنظیم سطح ثبت وقایع (log level). .IP "\fB-M\fP \fRname\fP" تعیین نام برای تابع اصلی (main) برای C، F77 یا Java. .IP "\fB-n\fP" منسوخ‌شده؛ قبلاً برای عدم مقداردهی اولیه داده‌ها به کار می‌رفت. .IP "\fB-N\fP \fRdatasetname\fP" تعیین نام مجموعه داده (dataset name). .IP "\fB-o\fP \fRnetcdf_file\fP" نام پرونده‌ای که به فراخوانی‌های «nc_create()» ارسال می‌شود. اگر این گزینه مشخص شود، به‌طور ضمنی (در غیاب هرگونه گزینه صریح \-l) بر گزینه «\fB-b\fP» دلالت دارد. این گزینه لازم است زیرا پرونده‌های netCDF را نمی‌توان مستقیماً در خروجی استاندارد نوشت، چرا که خروجی استاندارد قابلیت جستجو/جابه‌جایی (seekable) ندارد. .IP "\fB-P\fP" استفاده از حالت NC_DISKLESS برای ایجاد کامل پرونده در حافظه قبل از ذخیره‌سازی پایدار آن روی دیسک. .IP "\fB-W\fP \fRmaxwholevarsize\fP" تنظیم بیشینه اندازه متغیر کامل، به طوری که اگر تعداد کل عناصر کمتر از maxwholevarsize باشد، متغیر با یک فراخوانی منفرد nc_put_var به‌روزرسانی شود. نیاز به این دارد که متغیر هیچ بعد نامحدودی نداشته باشد. .IP "\fB-x\fP" عدم مقداردهی اولیه داده‌ها با مقادیر پرکننده (fill values). این گزینه می‌تواند ایجاد پرونده‌های بزرگ netCDF را بسیار تسریع کند، اما تلاش‌های بعدی برای خواندن داده‌های نوشته‌نشده از پرونده تولیدشده به سادگی قابل تشخیص نخواهد بود. .SH "مثال‌ها (EXAMPLES)" .LP بررسی نحو پرونده CDL با نام `\fBfoo.cdl\fP': .RS .HP ncgen foo.cdl .RE .LP تولید پرونده دودویی معادل netCDF با نام `\fBx.nc\fP' از روی پرونده CDL `\fBfoo.cdl\fP': .RS .HP ncgen \-o x.nc foo.cdl .RE .LP تولید یک برنامه C حاوی فراخوانی‌های توابع netCDF مورد نیاز برای ایجاد پرونده دودویی معادل netCDF با نام `\fBx.nc\fP' از روی پرونده CDL `\fBfoo.cdl\fP': .RS .HP ncgen \-lc foo.cdl >x.c .RE .LP .SH "نحوه استفاده (USAGE)" .SS "نمای کلی نحو CDL (CDL Syntax Overview)" .LP در زیر نمونه‌ای از نحو CDL آورده شده است که یک پرونده netCDF را با چندین بُعد نام‌گذاری‌شده (lat، lon و time)، متغیرها (Z، t، p، rh، lat، lon، time)، صفت‌های متغیر (units، long_name، valid_range، _FillValue) و مقداری داده توصیف می‌کند. کلیدواژه‌های CDL پررنگ (bold) شده‌اند. (این مثال صرفاً برای نشان دادن نحو است؛ یک پرونده واقعی CDL مجموعه کامل‌تری از صفت‌ها را خواهد داشت تا داده‌ها به‌طور کامل خودتوصیف‌گر باشند.) .RS .nf netcdf foo { // an example netCDF specification in CDL \fBtypes\fP: \fIubyte\fP \fIenum\fP enum_t {Clear = 0, Cumulonimbus = 1, Stratus = 2}; \fIopaque\fP(11) opaque_t; \fIint\fP(*) vlen_t; \fBdimensions\fP: lat = 10, lon = 5, time = \fIunlimited\fP ; \fBvariables\fP: \fIlong\fP lat(lat), lon(lon), time(time); \fIfloat\fP Z(time,lat,lon), t(time,lat,lon); \fIdouble\fP p(time,lat,lon); \fIlong\fP rh(time,lat,lon); \fIstring\fP country(time,lat,lon); \fIubyte\fP tag; // variable attributes lat:long_name = "latitude"; lat:units = "degrees_north"; lon:long_name = "longitude"; lon:units = "degrees_east"; time:units = "seconds since 1992-1-1 00:00:00"; // typed variable attributes \fIstring\fP Z:units = "geopotential meters"; \fIfloat\fP Z:valid_range = 0., 5000.; \fIdouble\fP p:_FillValue = \-9999.; \fIlong\fP rh:_FillValue = \-1; \fIvlen_t\fP :globalatt = {17, 18, 19}; \fBdata\fP: lat = 0, 10, 20, 30, 40, 50, 60, 70, 80, 90; lon = \-140, \-118, \-96, \-84, \-52; \fBgroup\fP: g { \fBtypes\fP: \fIcompound\fP cmpd_t { \fIvlen_t\fP f1; \fIenum_t\fP f2;}; } // group g \fBgroup\fP: h { \fBvariables\fP: /g/\fIcmpd_t\fP compoundvar; \fBdata\fP: compoundvar = { {3,4,5}, enum_t.Stratus } ; } // group h } .fi .RE .LP تمامی دستورات CDL با یک نقطه‌ویرگول (;) خاتمه می‌یابند. فاصله‌ها، تب‌ها و خطوط جدید را می‌توان آزادانه برای خوانایی بهتر استفاده کرد. توضیحات (کامنت‌ها) می‌توانند پس از نویسه‌های «//» در هر خطی قرار گیرند. .LP توصیف CDL از پنج بخش اختیاری تشکیل شده است: \fItypes\fP (انواع)، \fIdimensions\fP (ابعاد)، \fIvariables\fP (متغیرها)، \fIdata\fP (داده‌ها)، که به‌ترتیب با کلیدواژه‌های .BR `types:' ، .BR `dimensions:' ، .BR `variables:' ، و .BR `data:' آغاز می‌شوند. به چند نکته توجه فرمایید: (۱) کلیدواژه شامل دو‌نقطه پایانی است، بنابراین نباید قبل از نویسه دو‌نقطه فاصله‌ای وجود داشته باشد، و (۲) کلیدواژه‌ها حتماً باید با حروف کوچک نوشته شوند. .LP بخش \fBvariables:\fP می‌تواند شامل \fIاعلان‌های متغیرها\fP و \fIانتساب صفت‌ها\fP باشد. تمامی بخش‌ها می‌توانند شامل انتساب صفت‌های سراسری باشند. .LP علاوه بر این، پس از بخش \fBdata:\fP، کاربر می‌تواند مجموعه‌ای از گروه‌ها را تعریف کند (به مثال بالا نگاه کنید). گروه‌ها خود می‌توانند شامل انواع، ابعاد، متغیرها، داده‌ها و سایر گروه‌های تو‌در‌تو باشند. .LP بخش \fBtypes:\fP در netCDF انواع تعریف‌شده توسط کاربر را اعلان می‌کند. این انواع می‌توانند با استفاده از هر یک از انواع زیر ساخته شوند: \fBenum\fP، \fBvlen\fP، \fBopaque\fP یا \fBcompound\fP. .LP یک \fIبعد\fP (dimension) در netCDF برای تعیین شکل یک یا چند متغیر چندبُعدی موجود در پرونده netCDF استفاده می‌شود. یک بُعد netCDF دارای نام و اندازه است. یک بُعد می‌تواند دارای اندازه \fBunlimited\fP (نامحدود) باشد، بدین معنی که متغیری که از این بُعد استفاده می‌کند می‌تواند به هر طولی در آن بُعد گسترش یابد. .LP یک \fIمتغیر\fP بیانگر یک آرایه چندبُعدی از مقادیر با نوع داده یکسان است. یک متغیر دارای یک نام، نوع داده و شکلی است که توسط فهرست ابعاد آن توصیف می‌شود. هر متغیر همچنین می‌تواند علاوه بر مقادیر داده، \fIصفت‌ها\fPی متناظری (پایین‌تر را ببینید) داشته باشد. نام، نوع داده و شکل یک متغیر با اعلان آن در بخش \fIvariables\fP از توصیف CDL مشخص می‌شود. یک متغیر می‌تواند همنام با یک بُعد باشد؛ طبق قرارداد، چنین متغیری یک‌بُعدی است و حاوی مختصات بُعد همنام خود می‌باشد. ابعاد نیازی به داشتن متغیرهای متناظر ندارند. .LP یک \fIصفت\fP (attribute) در netCDF حاوی اطلاعاتی درباره یک متغیر netCDF یا درباره کل مجموعه داده netCDF است. صفت‌ها برای تعیین ویژگی‌هایی مانند واحدها، مقادیر ویژه، بیشینه و کمینه مقادیر معتبر، عوامل مقیاس‌بندی، آفست‌ها و پارامترها به کار می‌روند. اطلاعات صفت با مقادیر تکی یا آرایه‌ای از مقادیر نمایش داده می‌شوند. برای مثال، «units» صفتی است که با یک آرایه نویسه‌ای مانند «celsius» نمایش داده می‌شود. یک صفت دارای متغیر متناظر، یک نام، یک نوع داده، طول و مقدار است. بر خلاف متغیرها که برای نگهداری داده‌ها در نظر گرفته شده‌اند، صفت‌ها برای فراداده (داده درباره داده) در نظر گرفته شده‌اند. برخلاف netCDF-3، انواع صفت‌ها می‌توانند علاوه بر انواع توکار معمول، هر یک از انواع تعریف‌شده توسط کاربر نیز باشند. .LP در CDL، یک صفت با یک نوع، یک متغیر، یک «:» و سپس نام صفت مشخص می‌شود. نوع اختیاری است و در صورت عدم وجود، از مقادیر اختصاص‌یافته به صفت استنباط می‌شود. با حذف نام متغیر در اعلان صفت، امکان انتساب صفت‌های \fIسراسری\fP (global) که با هیچ متغیری مرتبط نیستند به کل netCDF وجود دارد. توجه داشته باشید که در مشخصاتی مانند: .nf x : a = ... .fi ابهام بالقوه‌ای وجود دارد. در این وضعیت، x می‌تواند یا نوعی برای یک صفت سراسری باشد، یا نام متغیر برای یک صفت. از آنجا که ممکن است هم نوعی به نام x و هم متغیری به نام x وجود داشته باشد، ابهام پیش می‌آید. قاعده بر این است که در این وضعیت، در صورت امکان x به‌عنوان یک نوع و در غیر این صورت به‌عنوان یک متغیر تفسیر می‌شود. .LP در صورت عدم تعیین، نوع داده صفت در CDL از روی نوع مقدار یا مقادیر منتسب به آن به دست می‌آید. طول یک صفت برابر با تعداد مقادیر داده منتسب به آن یا تعداد نویسه‌ها در رشته نویسه‌ای منتسب به آن است. برای صفت‌های غیرنویسه‌ای، چندین مقدار با جدا کردن مقادیر با ویرگول (,) انتساب داده می‌شوند. تمامی مقادیر منتسب به یک صفت باید از یک نوع باشند. .LP نام‌های ابعاد، متغیرها، صفت‌ها، انواع و گروه‌های CDL می‌توانند حاوی هر نویسه غیرکنترلی utf-8 به‌جز نویسه اسلش («/») باشند. با این حال، برخی نویسه‌ها در صورت استفاده در نام باید اسکیپ (escape) شوند، که در آن نویسه اسکیپ همان بک‌اسلش «\\» است. به ویژه اگر نویسه ابتدایی نام یک عدد (0-9) باشد، باید نویسه اسکیپ قبل از آن قرار گیرد. علاوه بر این، نویسه‌های « !"#$%&()*,:;<=>?[]^`\'{}|~\\» در صورت وقوع در هر کجای نام باید اسکیپ شوند. همچنین توجه داشته باشید که نام‌های صفت‌هایی که با زیرخط («_») آغاز می‌شوند، برای کاربرد Unidata رزرو شده‌اند و نباید در صفت‌های تعریف‌شده توسط کاربر استفاده شوند. .LP همچنین توجه داشته باشید که واژه‌های `variables' (متغیرها)، `dimensions' (ابعاد)، `data' (داده‌ها)، `group' (گروه) و `types' (انواع) نام‌های معتبر CDL هستند، اما هنگام استفاده به‌عنوان نام متغیر دقت کنید که بین آن‌ها و هر نویسه دو‌نقطه بعدی فاصله وجود داشته باشد. این موضوع عمدتاً در اعلان صفت‌ها اهمیت پیدا می‌کند. برای مثال، مورد زیر را در نظر بگیرید: .HP .RS .nf netcdf ... { ... variables: int dimensions; dimensions: attribute=0 ; // این مورد خطاست dimensions : attribute=0 ; // این مورد درست است ... } .fi .RE .LP بخش اختیاری \fBdata:\fP در مشخصات CDL جایی است که متغیرهای netCDF می‌توانند مقداردهی اولیه شوند. نحو مقداردهی اولیه ساده است: یک نام متغیر، یک علامت مساوی و فهرستی از ثوابت جداشده با ویرگول (احتمالاً با فاصله، تب و خطوط جدید) که به یک نقطه‌ویرگول ختم می‌شود. برای آرایه‌های چندبُعدی، آخرین بُعد سریع‌ترین تغییر را دارد. بنابراین برای ماتریس‌ها ترتیب سطری به جای ترتیب ستونی استفاده می‌شود. اگر مقادیر کمتری از میزان لازم برای پر کردن یک متغیر ارائه شود، با یک «مقدار پرکننده» (fill value) وابسته به نوع پر می‌شود که می‌توان آن را با تعیین مقداری برای صفت متغیر متمایز به نام «_FillValue» بازنویسی کرد. نوع ثوابت نیازی نیست دقیقاً مطابق با نوع اعلان‌شده برای متغیر باشد؛ تبدیل نوع خودکار (coercions) مثلاً برای تبدیل اعداد صحیح به اعداد اعشاری انجام می‌پذیرد. از ثابت «_» می‌توان برای تعیین مقدار پرکننده یک متغیر استفاده کرد. اگر نوع متغیر صریحاً «string» باشد، از ثابت ویژه «NIL» می‌توان برای نشان دادن یک رشته تهی استفاده کرد که مشابه یک رشته با طول صفر نیست. .SS "انواع داده‌های اولیه (Primitive Data Types)" .LP .RS .nf \fBchar\fP نویسه‌ها (characters) \fBbyte\fP داده‌های ۸-بیتی \fBshort\fP اعداد صحیح علامت‌دار ۱۶-بیتی \fBint\fP اعداد صحیح علامت‌دار ۳۲-بیتی \fBlong\fP (مترادف با \fBint\fP) \fBint64\fP اعداد صحیح علامت‌دار ۶۴-بیتی \fBfloat\fP ممیز شناور با دقت یگانه IEEE (۳۲ بیت) \fBreal\fP (مترادف با \fBfloat\fP) \fBdouble\fP ممیز شناور با دقت مضاعف IEEE (۶۴ بیت) \fBubyte\fP داده‌های ۸-بیتی بدون علامت \fBushort\fP اعداد صحیح بدون علامت ۱۶-بیتی \fBuint\fP اعداد صحیح بدون علامت ۳۲-بیتی \fBuint64\fP اعداد صحیح بدون علامت ۶۴-بیتی \fBstring\fP رشته‌هایی با طول دلخواه .fi .RE .LP زبان CDL از یک ابرمجموعه از انواع داده‌های اولیه در C پشتیبانی می‌کند. نام‌های انواع داده اولیه کلمات رزروشده در CDL هستند، بنابراین نام متغیرها، ابعاد و صفت‌ها نباید از نام‌های انواع اولیه باشد. در اعلان‌ها، نام انواع داده را می‌توان با حروف کوچک یا بزرگ مشخص کرد. .LP نوع Byte برای نگهداری هشت بیت کامل داده در نظر گرفته شده است و بایت صفر هیچ اهمیت ویژه‌ای ندارد، برخلاف آنچه برای داده‌های نویسه‌ای وجود دارد. ابزار \fBncgen\fP اعلان‌های \fBbyte\fP را به اعلان‌های \fBchar\fP در کد خروجی C و به اعلان غیراستاندارد \fBBYTE\fP در کد خروجی فرترن تبدیل می‌کند. .LP نوع Short می‌تواند مقادیری بین \-32768 و 32767 را نگهداری کند. ابزار \fBncgen\fP اعلان‌های \fBshort\fP را به اعلان‌های \fBshort\fP در کد خروجی C و به اعلان غیراستاندارد \fBINTEGER*2\fP در کد خروجی فرترن تبدیل می‌کند. .LP نوع Int می‌تواند مقادیری بین \-2147483648 و 2147483647 را نگهداری کند. ابزار \fBncgen\fP اعلان‌های \fBint\fP را به اعلان‌های \fBint\fP در کد خروجی C و به اعلان‌های \fBINTEGER\fP در کد خروجی فرترن تبدیل می‌کند. \fBlong\fP به‌عنوان مترادفی برای \fBint\fP در اعلان‌های CDL پذیرفته می‌شود، اما از آنجا که اکنون سکوهایی با بازنمایی ۶۴-بیتی برای long در C وجود دارند، منسوخ شده است. .LP نوع Int64 می‌تواند مقادیری بین \-9223372036854775808 و 9223372036854775807 را در بر گیرد. ابزار \fBncgen\fP اعلان‌های \fBint64\fP را به اعلان‌های \fBlonglong\fP در کد خروجی C تبدیل می‌کند. .\" and to \fBINTEGER\fP declarations in output Fortran code. .LP نوع Float می‌تواند مقادیری بین حدود \-3.4+38 و 3.4+38 را نگهداری کند. بازنمایی خارجی آن‌ها به‌صورت اعداد ممیز شناور استاندارد ۳۲-بیتی با دقت یگانه نرمال‌شده IEEE است. ابزار \fBncgen\fP اعلان‌های \fBfloat\fP را به اعلان‌های \fBfloat\fP در کد خروجی C و به اعلان‌های \fBREAL\fP در کد خروجی فرترن تبدیل می‌کند. \fBreal\fP به‌عنوان مترادفی برای \fBfloat\fP در اعلان‌های CDL پذیرفته می‌شود. .LP نوع Double می‌تواند مقادیری بین حدود \-1.7+308 و 1.7+308 را نگهداری کند. بازنمایی خارجی آن‌ها به‌صورت اعداد ممیز شناور استاندارد ۶۴-بیتی با دقت مضاعف نرمال‌شده IEEE است. ابزار \fBncgen\fP اعلان‌های \fBdouble\fP را به اعلان‌های \fBdouble\fP در کد خروجی C و به اعلان‌های \fBDOUBLE PRECISION\fP در کد خروجی فرترن تبدیل می‌کند. .LP معادل‌های بدون علامت انواع عدد صحیح فوق به انواع معادل بدون علامت C نگاشت می‌شوند. محدوده مقادیر آن‌ها به تناسب تغییر یافته و از صفر آغاز می‌شود. .LP تفسیر فنی نوع char این است که یک مقدار ۸-بیتی بدون علامت است. کدگذاری ۲۵۶ مقدار ممکن به‌طور پیش‌فرض نامشخص است. متغیری از نوع char می‌تواند با صفت «_Encoding» نشانه‌گذاری شود تا مجموعه نویسه‌های مورد استفاده را نشان دهد: US-ASCII، ISO-8859-1 و غیره. توجه داشته باشید که تعیین کدگذاری UTF-8 معادل با تعیین US-ASCII است، زیرا نویسه‌های چندبایتی UTF-8 را نمی‌توان در یک نویسه ۸-بیتی ذخیره کرد. تنها مقادیر معتبر تک‌بایتی UTF-8 طبق تعریف، کدگذاری ۷-بیتی US-ASCII با صفر بودن بیت بالایی هستند. .LP رشته‌ها به‌طور پیش‌فرض فرض می‌شوند که با UTF-8 کدگذاری شده‌اند. توجه داشته باشید که این بدان معناست که ممکن است کدگذاری‌های چندبایتی UTF-8 در رشته وجود داشته باشد، بنابراین ممکن است تعداد نویسه‌های متمایز UTF-8 در یک رشته کمتر از تعداد بایت‌های ۸-بیتی مورد استفاده برای ذخیره آن رشته باشد. .LP .SS "ثوابت CDL (CDL Constants)" .LP ثوابت منتسب به صفت‌ها یا متغیرها می‌توانند از هر یک از انواع پایه netCDF باشند. نحو ثوابت مشابه نحو C است، با این تفاوت که پسوندهای نوع باید به مقادیر short و float اضافه شوند تا از long و double متمایز گردند. .LP یک ثابت \fIbyte\fP با یک ثابت عدد صحیح با پسوند `b' (یا `B') نمایش داده می‌شود. در رابط قدیمی netCDF-2، ثوابت بایت را می‌شد با نویسه‌های تکی یا توالی‌های گریز نویسه‌ای استاندارد C مانند `a' یا `\n' نیز نمایش داد. این روش همچنان برای سازگاری با نسخه‌های پیشین پشتیبانی می‌شود، اما برای مشخص بودن تمایز بین نوع عددی byte و نوع متنی char منسوخ شده است. نمونه‌هایی از ثوابت byte عبارتند از: .RS .nf 0b // یک بایت صفر \-1b // \-1 به‌صورت یک بایت ۸-بیتی 255b // همچنین \-1 به‌صورت یک بایت ۸-بیتی علامت‌دار .fi .RE .LP ثوابت عدد صحیح \fIshort\fP برای نمایش مقادیر ۱۶-بیتی علامت‌دار در نظر گرفته شده‌اند. شکل یک ثابت \fIshort\fP به‌صورت یک ثابت عدد صحیح همراه با پسوند `s' یا `S' است. اگر یک ثابت \fIshort\fP با `0' آغاز شود، در مبنای ۸ (هشت‌هشتی) تفسیر می‌شود، مگر اینکه با `0x' شروع شود که در این صورت ثابت هگزادسیمال (شانزده‌شانزدهی) خواهد بود. برای مثال: .RS .nf \-2s // یک \-2 کوتاه (short) 0123s // مبنای ۸ 0x7ffs // مبنای ۱۶ .fi .RE .LP ثوابت عدد صحیح \fIint\fP برای نمایش مقادیر ۳۲-بیتی علامت‌دار در نظر گرفته شده‌اند. شکل یک ثابت \fIint\fP به‌صورت یک ثابت عدد صحیح معمولی است، اگرچه افزودن اختیاری یک نویسه `l' یا `L' منفرد نیز مجاز است (باز هم منسوخ شده است). اما دقت داشته باشید که پسوند L به‌عنوان یک عدد صحیح ۳۲-بیتی تفسیر می‌شود، و هرگز به‌عنوان عدد ۶۴-بیتی تلقی نخواهد شد. این مسئله ممکن است گیج‌کننده باشد زیرا نوع long در C می‌تواند به‌طور مبهم ۳۲-بیتی یا ۶۴-بیتی باشد. .LP اگر یک ثابت \fIint\fP با `0' آغاز شود، در مبنای ۸ تفسیر می‌شود، مگر اینکه با `0x' آغاز گردد که در این صورت یک ثابت هگزادسیمال خواهد بود (البته ثوابت مات/opaque را در ادامه ببینید). نمونه‌هایی از ثوابت معتبر \fIint\fP عبارتند از: .RS .nf \-2 1234567890L 0123 // مبنای ۸ 0x7ff // مبنای ۱۶ .fi .RE .LP ثوابت عدد صحیح \fIint64\fP برای نمایش مقادیر ۶۴-بیتی علامت‌دار به کار می‌روند. شکل یک ثابت \fIint64\fP به‌صورت یک ثابت عدد صحیح همراه با پسوند `ll' یا `LL' است. اگر یک ثابت \fIint64\fP با `0' آغاز شود در مبنای ۸ و اگر با `0x' آغاز شود در مبنای ۱۶ تفسیر می‌شود. برای مثال: .RS .nf \-2ll // مقدار \-2 علامت‌دار 0123LL // مبنای ۸ 0x7ffLL // مبنای ۱۶ .fi .RE .LP ثوابت ممیز شناور از نوع \fIfloat\fP برای بازنمایی داده‌های ممیز شناور با حدود هفت رقم بااهمیت مناسب هستند. شکل یک ثابت \fIfloat\fP همانند ثابت ممیز شناور C همراه با پسوند `f' یا `F' است. برای مثال موارد زیر همگی ثوابت معتبر \fIfloat\fP هستند: .RS .nf \-2.0f 3.14159265358979f // دقت آن کاهش می‌یابد 1.f .fi .RE .LP ثوابت ممیز شناور از نوع \fIdouble\fP برای بازنمایی داده‌های ممیز شناور با حدود شانزده رقم بااهمیت مناسب هستند. شکل ثابت \fIdouble\fP همانند ثابت ممیز شناور C است. یک `d' یا `D' اختیاری می‌تواند به آن افزوده شود. برای مثال، موارد زیر همگی ثوابت معتبر \fIdouble\fP هستند: .RS .nf \-2.0 3.141592653589793 1.0e-20 1.d .fi .RE .LP ثوابت اعداد صحیح بدون علامت را می‌توان با افزودن نویسه 'U' یا 'u' بین مقدار ثابت و هر مشخص‌کننده اندازه پس از آن، یا بلافاصله در انتهای مشخص‌کننده اندازه ایجاد کرد. بنابراین می‌توان برای مثال عباراتی چون 10U، 100su، 100000ul یا 1000000llu نوشت. .LP ثوابت نویسه‌ای تک‌نویسه‌ای ممکن است در گیومه تکی قرار گیرند. اگر توالی از یک یا چند نویسه در گیومه دوتایی قرار گیرد، تفسیر آن باید از متن استنباط شود. اگر مجموعه داده با مدل کلاسیک netCDF ایجاد شده باشد، تمام چنین ثوابتی به‌صورت آرایه‌ای از نویسه‌ها تفسیر می‌شوند، بنابراین هر نویسه در ثابت طوری تفسیر می‌شود که گویی یک نویسه تکی بوده است. اگر مجموعه داده به‌صورت netCDF گسترش‌یافته باشد، آنگاه بسته به نوع صفت یا متغیری که رشته در آن گنجانده شده است، ثابت ممکن است مانند مدل کلاسیک یا مانند یک رشته واقعی (پایین‌تر را ببینید) تفسیر گردد. .LP تفسیر ثوابت char بدین گونه است که مواردی که در محدوده ASCII قابل چاپ هستند (' '..'~') فرض می‌شود که به‌صورت زیرمجموعه ۱-بایتی UTF-8 کدگذاری شده‌اند که معادل US-ASCII است. در تمامی موارد، قواعد مرسوم گریز رشته‌ها در C برای مقادیر از ۰ تا ۱۲۷ رعایت می‌شود. مقادیر بزرگتر از ۱۲۷ مجاز هستند، اما کدگذاری آن‌ها تعریف‌نشده است. برای netCDF گسترش‌یافته، استفاده از نوع char به نفع نوع string منسوخ شده است. .LP چند نمونه از ثوابت نویسه‌ای به شرح زیر است: .RS .nf 'a' // نویسه اسکی `a' "a" // معادل با 'a' "Two\\nlines\\n" // یک رشته ۱۰ نویسه‌ای با دو خط جدید درونی "a bell:\\007" // یک رشته حاوی زنگ اسکی .fi .RE توجه داشته باشید که آرایه نویسه‌ای netCDF با مقدار "a" در یک متغیر تک‌عنصری جای می‌گیرد، چرا که هیچ نویسه پایانی NULL فرض نمی‌شود. با این حال، یک بایت صفر در یک آرایه نویسه‌ای توسط برنامه \fBncdump\fP با پیروی از قرارداد C به‌عنوان پایان نویسه‌های معنادار تفسیر می‌شود. بنابراین، یک بایت NULL نباید درون یک رشته نویسه‌ای قرار گیرد مگر در انتهای آن؛ در عوض برای آرایه‌های بایتی حاوی بایت صفر، از نوع داده \fIbyte\fP استفاده کنید. .LP ثوابت رشته‌ای (\fIString\fP)، همانند ثوابت نویسه‌ای، با گیومه دوتایی نمایش داده می‌شوند. این امر یک ابهام بالقوه ایجاد می‌کند چرا که یک رشته چندنویسه‌ای می‌تواند نشان‌دهنده یک مقدار نویسه‌ای دارای بُعد نیز باشد. رفع ابهام معمولاً بر اساس زمینه انجام می‌شود، اما باید دقت شود که نوع \fIstring\fP مشخص گردد تا انتخاب درست تضمین شود. ثوابت رشته‌ای همیشه دارای کدگذاری UTF-8 فرض می‌شوند. این موضوع مشخصاً بدان معناست که ثابت رشته‌ای ممکن است در واقع حاوی نویسه‌های چندبایتی UTF-8 باشد. از ثابت ویژه `NIL` می‌توان برای نشان دادن یک رشته تهی استفاده کرد، که مشابه یک رشته با طول صفر نیست. .LP ثوابت مات (\fIOpaque\fP) به‌صورت دنباله‌ای از ارقام هگزادسیمال همراه با پیشوند 0X یا 0x نمایش داده می‌شوند: مانند 0xaa34ffff. این ثوابت همچنان می‌توانند به‌عنوان ثوابت عدد صحیح استفاده شوند و بر حسب نیاز کوتاه‌سازی یا گسترش می‌یابند. .SS "عبارات ثابت مرکب (Compound Constant Expressions)" .LP به منظور انتساب مقادیر به متغیرها (یا صفت‌هایی) که نوع آن‌ها از نوع تعریف‌شده توسط کاربر است، نماد ثابت گسترش یافته تا دنباله‌ای از ثوابت محصور در آکولاد (مانند "{"..."}") را در بر گیرد. به چنین ثابتی یک ثابت مرکب گفته می‌شود و ثوابت مرکب می‌توانند تو‌در‌تو باشند. .LP به ازای نوع "T(*) vlen_t"، که در آن T نوع پایه دلخواه دیگری است، ثوابت مربوط به آن باید به صورت زیر مشخص شوند: .nf vlen_t var[2] = {t11,t12,...t1N}, {t21,t22,...t2m}; .fi فرض می‌شود مقادیر tij ثوابتی از نوع T هستند. .LP به ازای نوع "compound cmpd_t {T1 f1; T2 f2...Tn fn}"، که در آن Ti انواع پایه دلخواه دیگر هستند، ثوابت مربوط به آن باید به صورت زیر مشخص شوند: .nf cmpd_t var[2] = {t11,t12,...t1N}, {t21,t22,...t2n}; .fi فرض می‌شود مقادیر tij ثوابتی از نوع Ti هستند. اگر فیلدها وجود نداشته باشند، با استفاده از هر مقدار پرکننده مشخص‌شده یا پیش‌فرض برای نوع پایه آن فیلد تنظیم خواهند شد. .LP مجموعه عمومی قواعد برای استفاده از آکولادها در بخش .B تعیین .B فهرست‌های داده در ادامه تعریف شده است. .LP .SS "قواعد حوزه دید (Scoping Rules)" .LP با اضافه شدن گروه‌ها، فضای نام اشیای تعریف‌شده دیگر مسطح نیست. به ارجاعات (نام‌های) هر نوع، بُعد یا متغیر می‌توان مسیر مطلقی که اعلان خاصی را مشخص می‌کند اضافه کرد. بدین ترتیب می‌توان نوشت: .nf variables: /g1/g2/t1 v1; .fi نوعی که به آن ارجاع داده شده (t1) نوع موجود در گروه g2 است که خود درون گروه g1 قرار دارد. شباهت این نمادگذاری به مسیرهای پرونده در یونیکس تعمدی است و می‌توان گروه‌ها را ساختاری شبیه به ساختار دایرکتوری در نظر گرفت. .LP هنگامی که نامی فاقد پیشوند مسیر باشد، قواعد حوزه دید برای یافتن اعلان مربوطه اعمال می‌شوند. در حال حاضر سه قاعده وجود دارد: یکی برای ابعاد، یکی برای انواع و ثوابت شمارشی، و دیگری برای تمام موارد دیگر. .HP ۱. هنگامی که نام بدون پیشوند یک بُعد استفاده می‌شود (مانند اعلان یک متغیر)، ابزار ncgen ابتدا در گروه دربرگیرنده فوری به دنبال آن بُعد می‌گردد. اگر در آنجا یافت نشد، در گروه دربرگیرنده آن گروه جستجو می‌کند. این روند در سلسله‌مراتب گروه‌ها ادامه می‌یابد تا زمانی که بُعد پیدا شود یا گروه دیگری برای جستجو باقی نمانده باشد. .HP ۲. هنگامی که یک نام بدون پیشوند از یک نوع یا ثابت شمارشی استفاده می‌شود، ncgen درخت گروه‌ها را با استفاده از جستجوی عمق‌اول پیش‌ترتیب جستجو می‌کند. این اساساً بدان معنی است که اعلان متناظری را می‌یابد که به لحاظ متنی در پرونده cdl قبل از ارجاع آمده و در سلسله‌مراتب گروه‌ها «بالاترین» باشد. .HP ۳. برای تمام نام‌های دیگر، تنها گروه دربرگیرنده فوری جستجو می‌شود. .LP یک نکته پایانی: ارجاع به جلو (forward reference) مجاز نیست. این بدان معناست که برای مثال، تعیین ‎/g1/g2/t1 اگر قبل از تعریف g1 یا g2 رخ دهد، با خطا مواجه خواهد شد. .SS "تعیین ثوابت شمارشی (Specifying Enumeration Constants)" .LP ارجاع به ثوابت شمارشی (در فهرست‌های داده) ممکن است مبهم باشد، زیرا نام یکسانی از یک ثابت شمارشی می‌تواند در بیش از یک نوع شمارش تعریف شده باشد. اگر یک پرونده cdl ثابتی مبهم را مشخص کند، ncgen خطا صادر خواهد کرد. چنین ثوابتی را می‌توان به دو روش ابهام‌زدایی کرد: .IP "\fB1.\fP" افزودن نام شمارش به ابتدای ثابت شمارشی همراه با یک نقطه؛ برای مثال: \fIenum.econst\fP. .IP "\fB2.\fP" اگر مورد اول برای رفع ابهام ثابت شمارشی کافی نباشد، باید نوع دقیق شمارش را با استفاده از مسیر گروه مشخص کرد؛ برای مثال: \fI/g1/g2/enum.econst\fP. .SS "صفت‌های ویژه (Special Attributes)" .LP صفت‌های ویژه و مجازی را می‌توان برای ارائه اطلاعات مربوط به کارایی در مورد قالب پرونده و ویژگی‌های متغیرها مشخص کرد. برای اثربخشی این صفت‌ها، پرونده باید یک پرونده netCDF-4 باشد. .LP این صفت‌های مجازی ویژه در واقع بخشی از پرونده نیستند، بلکه صرفاً روشی مناسب برای تنظیم ویژگی‌های گوناگون داده‌ها در CDL هستند. .LP صفت‌های ویژه‌ای که در حال حاضر پشتیبانی می‌شوند عبارتند از: `_Format' ، `_Fletcher32' ، `_ChunkSizes' ، `_Endianness' ، `_DeflateLevel' ، `_Shuffle' و `_Storage'. .LP صفت `_Format' یک صفت سراسری است که گونه قالب netCDF را مشخص می‌کند. مقدار آن باید یک رشته تکی منطبق بر یکی از مقادیر `classic'، `64-bit offset'، `64-bit data'، `netCDF-4' یا `netCDF-4 classic model' باشد. .LP باقی صفت‌های ویژه همگی صفت‌های متغیر هستند. اساساً همه آن‌ها به تابع متناظر `nc_def_var_XXX' طبق تعریف در رابط برنامه‌نویسی netCDF-4 نگاشت می‌شوند. برای صفت‌هایی که اساساً بولی هستند (_Fletcher32، _Shuffle و _NOFILL)، مقدار true را می‌توان با استفاده از رشته‌های `true' یا `1'، یا با عدد صحیح 1 مشخص کرد. مقدار false نیازمند `false'، `0' یا عدد صحیح 0 است. عملیات مرتبط با این صفت‌ها به شرح زیر است: .IP 1. 3 صفت `_Fletcher32' ویژگی «fletcher32» را برای یک متغیر تنظیم می‌کند. .IP 2. 3 صفت `_Endianness' بسته به نحوه ذخیره‌سازی متغیر در اولین نوشتن، `little' یا `big' است. .IP 3. 3 اگر فشرده‌سازی برای متغیر تعیین شده باشد، صفت `_DeflateLevel' یک عدد صحیح بین 0 تا 9 (شامل هر دو) است. .IP 4. 3 صفت `_Shuffle' تعیین می‌کند که آیا فیلتر shuffle باید استفاده شود یا خیر. .IP 5. 3 صفت `_Storage' برابر با `contiguous' یا `compact' یا `chunked' است. .IP 6. 3 صفت `_ChunkSizes' فهرستی از اندازه‌های قطعات (chunk sizes) برای هر بُعد متغیر است. .LP توجه داشته باشید که صفت‌هایی چون "add_offset" یا "scale_factor" معنای ویژه‌ای برای ncgen ندارند. این صفت‌ها در حال حاضر قراردادهایی هستند که بالاتر از لایه کتابخانه توسط سایر بسته‌های کمکی مانند NCO مدیریت می‌شوند. .LP .SS "تعیین فهرست‌های داده (Specifying Datalists)" .LP تعیین فهرست‌های داده برای متغیرها در بخش `data:` ممکن است تا حدی پیچیده باشد. برخی قواعد وجود دارند که باید رعایت شوند تا اطمینان حاصل شود که فهرست‌های داده به‌درستی توسط ncgen تجزیه می‌شوند. .LP نخست، سطح بالا به‌طور خودکار فهرستی از اقلام فرض می‌شود، بنابراین نباید درون {...} قرار گیرد. این بدان معناست که اگر متغیر یک اسکالر (scalar) باشد، یک عنصر تک در سطح بالا وجود خواهد داشت و اگر متغیر یک آرایه باشد، N عنصر در سطح بالا وجود خواهد داشت. برای هر عنصر از فهرست سطح بالا، قواعد زیر باید اعمال شوند: .IP 1. 3 نمونه‌های ابعاد UNLIMITED (به‌جز بُعد اول) باید برای تعیین اندازه در {...} محصور شوند. .IP 2. 3 نمونه‌های مرکب (compound) باید در {...} گنجانده شوند. .IP 3. 3 فیلدهای غیر‌اسکالر نمونه‌های مرکب باید در {...} گنجانده شوند. .IP 4. 3 نمونه‌های vlen باید برای تعیین اندازه در {...} محصور شوند. .LP فهرست‌های داده مرتبط با صفت‌ها به‌طور ضمنی یک بردار (یعنی فهرستی) از مقادیر نوع آن صفت هستند و قواعد بالا باید با در نظر داشتن این نکته اعمال شوند. .IP 7. 3 هیچ کاربرد دیگری از آکولاد مجاز نیست. .LP توجه داشته باشید یکی از پیامدهای این قواعد این است که آرایه‌هایی از مقادیر نمی‌توانند زیر‌آرایه‌هایی درون آکولاد داشته باشند. برای مثال، int var(d1)(d2)...(dn) را در نظر بگیرید، که در آن هیچ‌یک از d2...dn نامحدود نیستند. فهرست داده برای این متغیر باید یک فهرست منفرد از اعداد صحیح باشد، که تعداد اعداد صحیح بیش از D=d1*d2*...dn مقدار نباشد؛ توجه داشته باشید که فهرست می‌تواند کمتر از D باشد که در این صورت از مقادیر پرکننده (fill values) برای تکمیل فهرست استفاده خواهد شد. .LP قاعده شماره ۶ درباره فهرست داده صفت‌ها پیامد زیر را دارد: اگر نوع صفت یک نوع مرکب (یا vlen) باشد و اگر تعداد مدخل‌ها در فهرست یکی باشد، نمونه‌های مرکب باید در آکولاد محصور شوند. .LP .SS "تعیین فهرست‌های داده نویسه‌ای (Specifying Character Datalists)" .LP تعیین فهرست‌های داده برای متغیرهایی از نوع char نیز با پیچیدگی‌هایی همراه است. برای مثال موارد زیر را در نظر بگیرید: .RS .nf dimensions: u=UNLIMITED; d1=1; d2=2; d3=3; d4=4; d5=5; u2=UNLIMITED; variables: char var(d4,d5); datalist: var="1", "two", "three"; .fi .RE .LP ما بیست عنصر از var برای پر کردن داریم (d5 X d4) و سه رشته به طول‌های ۱، ۳ و ۵ داریم. چگونه نویسه‌ها را در رشته‌ها به این بیست عنصر اختصاص می‌دهیم؟ .LP این موضوع چالش‌برانگیز است زیرا مطلوب است که رفتار ncgen اصلی (ncgen3) شبیه‌سازی شود. الگوریتم اصلی مفهوماً به شرح زیر است: .IP 1. 3 فرض کنید مجموعه‌ای از ابعاد D1..Dn داریم، که در آن D1 می‌تواند به‌طور اختیاری یک بُعد نامحدود باشد. فرض بر این است که اندازه تمام Diها مشخص است (شامل ابعاد نامحدود). .IP 2. 3 با داشتن دنباله‌ای از ثوابت رشته‌ای یا نویسه‌ای C1..Cm، هدف ما ساخت یک رشته منفرد است که طول آن حاصل‌ضرب دکارتی D1 تا Dn باشد. توجه داشته باشید که برای اهداف این الگوریتم، ثوابت نویسه‌ای به‌صورت رشته‌هایی به اندازه ۱ تلقی می‌شوند. .IP 3. 3 حاصل‌ضرب دکارتی D1 تا D(n-1) را با عنوان Dx بسازید. .IP 4. 3 برای هر ثابت Ci، نویسه‌های پرکننده را در صورت نیاز اضافه کنید تا طول آن مضربی از Dn شود. .IP 5. 3 ثوابت اصلاح‌شده C1..Cm را به هم متصل کنید تا رشته S تولید شود. .IP 6. 3 نویسه‌های پرکننده را به S اضافه کنید تا طول آن مضربی از Dn شود. .IP 8. 3 اگر S طولانی‌تر از Dx * Dn باشد، آن را کوتاه کرده و یک هشدار صادر کنید. .LP سه حالت دیگر نیز شایان توجه است: .IP 1. 3 اگر تنها یک بُعد منفرد و نامحدود وجود داشته باشد، تمام ثوابت به هم متصل می‌شوند و نویسه‌های پرکننده به انتهای رشته حاصل افزوده می‌شوند تا طول آن برابر با اندازه بُعد نامحدود شود. اگر طول بزرگتر از بُعد نامحدود باشد، همراه با یک هشدار کوتاه می‌شود. .IP 2. 3 در مورد vlen با نوع نویسه‌ای، برای مثال «char(*) vlen_t»، ما به سادگی تمام ثوابت را بدون هیچ‌گونه پرکردنی به هم متصل می‌کنیم. .IP 3. 3 در مورد صفت از نوع نویسه‌ای، ما به سادگی تمام ثوابت را به هم متصل می‌کنیم. .LP در netcdf-4، ابعادی به غیر از بُعد اول نیز می‌توانند نامحدود باشند. مسلماً طبق قواعد فوق، نمونه‌های نامحدود درونی باید با {...} جدا شوند. برای مثال: .in +5 .nf variables: char var(u,u2); datalist: var={"1", "two"}, {"three"}; .fi .in -5 در این حالت u دارای طول مؤثر دو خواهد بود. درون هر نمونه از u2، قواعد فوق اعمال می‌شوند و به این حالت منجر می‌گردند: .in +5 datalist: var={"1","t","w","o"}, {"t","h","r","e","e"}; .in -5 اندازه مؤثر u2 بیشینه طول دو نمونه خواهد بود (در این مورد پنج) و مورد کوتاه‌تر پر می‌شود تا این حالت ایجاد شود: .in +5 datalist: var={"1","t","w","o","\\0"}, {"t","h","r","e","e"}; .in -5 .LP یک مورد پیچیده‌تر را در نظر بگیرید: .in +5 .nf variables: char var(u,u2,u3); datalist: var={{"1", "two"}}, {{"three"},{"four","xy"}}; .fi .in -5 در این مورد نیز u دوباره دارای طول مؤثر دو خواهد بود. ابعاد u2 دارای اندازه = max(1,2) = 2 خواهند بود. درون هر نمونه از u2، قواعد فوق اعمال می‌شوند و به این حالت می‌انجامند: .in +5 .nf datalist: var={{"1","t","w","o"}}, {{"t","h","r","e","e"},{"f","o","u","r","x","y"}}; .fi .in -5 اندازه مؤثر u3 بیشینه طول دو نمونه خواهد بود (در این مورد شش) و موارد کوتاه‌تر پر می‌شوند تا این مورد به دست آید: .in +5 .nf datalist: var={{"1","t","w","o","\0","\0"}}, {{"t","h","r","e","e","\0"},{"f","o","u","r","x","y"}}; .fi .in -5 با این حال توجه داشته باشید که اولین نمونه u2 کمتر از حداکثر طول u2 است، بنابراین باید یک پرکننده برای نمونه دیگری از u2 اضافه کنیم که منجر به موارد زیر می‌شود: .in +5 .nf datalist: var={{"1","t","w","o","\0","\0"},{"\0","\0","\0","\0","\0","\0"}}, {{"t","h","r","e","e","\0"},{"f","o","u","r","x","y"}}; .fi .in -5 .SH "اشکالات (BUGS)" .LP برنامه‌های تولیدشده توسط \fBncgen\fP هنگام استفاده از گزینه \fB-c\fP از دستورات مقداردهی اولیه برای ذخیره داده‌ها در متغیرها استفاده می‌کنند، و اگر بخواهید از آن‌ها برای مجموعه‌های داده بزرگ استفاده کنید، در تولید برنامه‌های قابل کامپایل با شکست مواجه می‌شوند، زیرا دستورات حاصل ممکن است از طول خط یا تعداد خطوط ادامه‌دار مجاز توسط کامپایلر فراتر روند. .LP نحو CDL انتساب آنچه را که شبیه به آرایه‌ای از رشته‌های با طول متغیر به نظر می‌رسد به یک متغیر netCDF آسان می‌کند، اما رشته‌ها ممکن است به سادگی در یک آرایه منفرد از نویسه‌ها ادغام شوند. استفاده مشخص از مشخص‌کننده نوع \fIstring\fP می‌تواند این مشکل را برطرف کند. .SH "شناسه‌ها و کلیدواژه‌ها (Identifiers and Keywords)" .LP تحت شرایط خاصی، برخی کلیدواژه‌ها را می‌توان به‌عنوان شناسه استفاده کرد: .IP "\fB1.\fP" اگر یک کلیدواژه نوع، جزو انواع پشتیبانی‌شده توسط قالب پرونده cdl. نباشد، می‌تواند به‌عنوان شناسه استفاده شود. بنابراین، برای مثال هنگام تبدیل یک پرونده cdl. به یک پرونده netCDF-3، می‌توان از «string» یا «uint64» به‌عنوان شناسه استفاده کرد. .IP "\fB2.\fP" کلیدواژه «data» می‌تواند به‌عنوان شناسه استفاده شود، زیرا می‌توان آن را به‌صورت حساس به متن بررسی کرد تا مشخص شود که «data» یک کلیدواژه است یا یک شناسه. .SH "گرامر CDL (CDL Grammar)" .LP پرونده ncgen.y گرامر مرجع و قطعی برای CDL است، اما نسخه‌ای خلاصه‌شده در اینجا برای کامل بودن آورده شده است. .RS .nf ncdesc: NETCDF datasetid rootgroup ; datasetid: DATASETID rootgroup: '{' groupbody subgrouplist '}'; groupbody: attrdecllist typesection dimsection vasection datasection ; subgrouplist: /*empty*/ | subgrouplist namedgroup ; namedgroup: GROUP ident '{' groupbody subgrouplist '}' attrdecllist ; typesection: /* empty */ | TYPES | TYPES typedecls ; typedecls: type_or_attr_decl | typedecls type_or_attr_decl ; typename: ident ; type_or_attr_decl: typedecl | attrdecl ';' ; typedecl: enumdecl optsemicolon | compounddecl optsemicolon | vlendecl optsemicolon | opaquedecl optsemicolon ; optsemicolon: /*empty*/ | ';' ; enumdecl: primtype ENUM typename ; enumidlist: enumid | enumidlist ',' enumid ; enumid: ident '=' constint ; opaquedecl: OPAQUE '(' INT_CONST ')' typename ; vlendecl: typeref '(' '*' ')' typename ; compounddecl: COMPOUND typename '{' fields '}' ; fields: field ';' | fields field ';' ; field: typeref fieldlist ; primtype: CHAR_K | BYTE_K | SHORT_K | INT_K | FLOAT_K | DOUBLE_K | UBYTE_K | USHORT_K | UINT_K | INT64_K | UINT64_K ; dimsection: /* empty */ | DIMENSIONS | DIMENSIONS dimdecls ; dimdecls: dim_or_attr_decl ';' | dimdecls dim_or_attr_decl ';' ; dim_or_attr_decl: dimdeclist | attrdecl ; dimdeclist: dimdecl | dimdeclist ',' dimdecl ; dimdecl: dimd '=' UINT_CONST | dimd '=' INT_CONST | dimd '=' DOUBLE_CONST | dimd '=' NC_UNLIMITED_K ; dimd: ident ; vasection: /* empty */ | VARIABLES | VARIABLES vadecls ; vadecls: vadecl_or_attr ';' | vadecls vadecl_or_attr ';' ; vadecl_or_attr: vardecl | attrdecl ; vardecl: typeref varlist ; varlist: varspec | varlist ',' varspec ; varspec: ident dimspec ; dimspec: /* empty */ | '(' dimlist ')' ; dimlist: dimref | dimlist ',' dimref ; dimref: path ; fieldlist: fieldspec | fieldlist ',' fieldspec ; fieldspec: ident fielddimspec ; fielddimspec: /* empty */ | '(' fielddimlist ')' ; fielddimlist: fielddim | fielddimlist ',' fielddim ; fielddim: UINT_CONST | INT_CONST ; /* Use this when referencing defined objects */ varref: type_var_ref ; typeref: type_var_ref ; type_var_ref: path | primtype ; /* Use this for all attribute decls */ /* Watch out; this is left recursive */ attrdecllist: /*empty*/ | attrdecl ';' attrdecllist ; attrdecl: ':' ident '=' datalist | typeref type_var_ref ':' ident '=' datalist | type_var_ref ':' ident '=' datalist | type_var_ref ':' _FILLVALUE '=' datalist | typeref type_var_ref ':' _FILLVALUE '=' datalist | type_var_ref ':' _STORAGE '=' conststring | type_var_ref ':' _CHUNKSIZES '=' intlist | type_var_ref ':' _FLETCHER32 '=' constbool | type_var_ref ':' _DEFLATELEVEL '=' constint | type_var_ref ':' _SHUFFLE '=' constbool | type_var_ref ':' _ENDIANNESS '=' conststring | type_var_ref ':' _NOFILL '=' constbool | ':' _FORMAT '=' conststring ; path: ident | PATH ; datasection: /* empty */ | DATA | DATA datadecls ; datadecls: datadecl ';' | datadecls datadecl ';' ; datadecl: varref '=' datalist ; datalist: datalist0 | datalist1 ; datalist0: /*empty*/ ; /* Must have at least 1 element */ datalist1: dataitem | datalist ',' dataitem ; dataitem: constdata | '{' datalist '}' ; constdata: simpleconstant | OPAQUESTRING | FILLMARKER | NIL | econstref | function ; econstref: path ; function: ident '(' arglist ')' ; arglist: simpleconstant | arglist ',' simpleconstant ; simpleconstant: CHAR_CONST /* never used apparently*/ | BYTE_CONST | SHORT_CONST | INT_CONST | INT64_CONST | UBYTE_CONST | USHORT_CONST | UINT_CONST | UINT64_CONST | FLOAT_CONST | DOUBLE_CONST | TERMSTRING ; intlist: constint | intlist ',' constint ; constint: INT_CONST | UINT_CONST | INT64_CONST | UINT64_CONST ; conststring: TERMSTRING ; constbool: conststring | constint ; /* Push all idents thru here for tracking */ ident: IDENT ; .fi .RE