OPTIN.C 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428
  1. /****************************************************************************
  2. * optin.c
  3. *
  4. * This module contains functions for ini-file/command line parsing, streams.
  5. *
  6. * from Persistence of Vision(tm) Ray Tracer
  7. * Copyright 1996,1999 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. * NOTICE: This source code file is provided so that users may experiment
  10. * with enhancements to POV-Ray and to port the software to platforms other
  11. * than those supported by the POV-Ray Team. There are strict rules under
  12. * which you are permitted to use this file. The rules are in the file
  13. * named POVLEGAL.DOC which should be distributed with this file.
  14. * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. * Team Coordinator by email to team-coord@povray.org or visit us on the web at
  16. * http://www.povray.org. The latest version of POV-Ray may be found at this site.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. *****************************************************************************/
  23. /****************************************************************************
  24. *
  25. * This file contains the routines to implement an .INI file parser that can
  26. * parse options in the form "Variable=value" or traditional POV-Ray
  27. * command-line switches. Values can come from POVRAYOPT, command-line,
  28. * .DEF or .INI files.
  29. *
  30. * Written by CEY 4/94 based on existing code and INI code from CDW.
  31. *
  32. * ---
  33. *
  34. * Modification by Thomas Willhalm, March 1999, used with permission.
  35. *
  36. *****************************************************************************/
  37. #include <ctype.h>
  38. #include <time.h>
  39. #include "frame.h"
  40. #include "povproto.h"
  41. #include "bbox.h"
  42. #include "lighting.h"
  43. #include "mem.h" /*POV_FREE*/
  44. #include "octree.h"
  45. #include "povray.h"
  46. #include "optin.h"
  47. #include "optout.h"
  48. #include "parse.h"
  49. #include "radiosit.h"
  50. #include "render.h"
  51. #include "tokenize.h"
  52. #include "vlbuffer.h"
  53. #include "ppm.h"
  54. #include "targa.h"
  55. #include "userio.h"
  56. #include "png_pov.h"
  57. /*****************************************************************************
  58. * Local preprocessor defines
  59. ******************************************************************************/
  60. /*****************************************************************************
  61. * Local typedefs
  62. ******************************************************************************/
  63. /*****************************************************************************
  64. * Local variables
  65. ******************************************************************************/
  66. char *DefaultFile[] =
  67. {
  68. "debug.out",
  69. "fatal.out",
  70. "render.out",
  71. "stats.out",
  72. "warning.out",
  73. "alltext.out"
  74. };
  75. int inflag, outflag;
  76. /* Quality constants */
  77. long Quality_Values[12]=
  78. {
  79. QUALITY_0, QUALITY_1, QUALITY_2, QUALITY_3, QUALITY_4,
  80. QUALITY_5, QUALITY_6, QUALITY_7, QUALITY_8, QUALITY_9
  81. };
  82. /* Keywords for the ini-file parser. */
  83. struct Reserved_Word_Struct Option_Variable [] =
  84. {
  85. { ALL_CONSOLE_OP, "All_Console" },
  86. { ALL_FILE_OP, "All_File" },
  87. { ANTIALIAS_DEPTH_OP, "Antialias_Depth" },
  88. { ANTIALIAS_OP, "Antialias" },
  89. { ANTIALIAS_THRESH_OP, "Antialias_Threshold" },
  90. { BOUNDING_OP, "Bounding" },
  91. { BOUNDING_THRESH_OP, "Bounding_Threshold" },
  92. { BUFFERED_OUTPUT_OP,"Buffer_Output" },
  93. { BUF_SIZE_OP, "Buffer_Size" },
  94. { CLOCK_OP, "Clock" },
  95. { CONTINUE_OP, "Continue_Trace" },
  96. { CREATE_INI_OP, "Create_Ini" },
  97. { CYCLIC_ANIMATION_OP, "Cyclic_Animation" },
  98. { DEBUG_CONSOLE_OP, "Debug_Console" },
  99. { DEBUG_FILE_OP, "Debug_File" },
  100. { DISPLAY_OP, "Display" },
  101. { DISPLAY_GAMMA_OP, "Display_Gamma" },
  102. { DRAW_VISTAS_OP, "Draw_Vistas" },
  103. { END_COLUMN_OP, "End_Column" },
  104. { END_ROW_OP, "End_Row" },
  105. { FATAL_CONSOLE_OP, "Fatal_Console" },
  106. { FATAL_ERROR_CMD_OP, "Fatal_Error_Command" },
  107. { FATAL_ERROR_RET_OP, "Fatal_Error_Return" },
  108. { FATAL_FILE_OP, "Fatal_File" },
  109. { FIELD_RENDER_OP, "Field_Render" },
  110. { FILE_OUTPUT_OP, "Output_to_File" },
  111. { FILE_OUTPUT_TYPE_OP, "Output_File_Type" },
  112. { FINAL_CLOCK_OP, "Final_Clock" },
  113. { FINAL_FRAME_OP, "Final_Frame" },
  114. { HEIGHT_OP, "Height" },
  115. { HIST_NAME_OP, "Histogram_Name" },
  116. { HIST_SIZE_OP, "Histogram_Grid_Size" },
  117. { HIST_TYPE_OP, "Histogram_Type" },
  118. { INITIAL_CLOCK_OP, "Initial_Clock" },
  119. { INITIAL_FRAME_OP, "Initial_Frame" },
  120. { INPUT_FILE_NAME_OP, "Input_File_Name" },
  121. { JITTER_AMOUNT_OP, "Jitter_Amount" },
  122. { JITTER_OP, "Jitter" },
  123. { LIBRARY_PATH_OP, "Library_Path" },
  124. { LIGHT_BUFFER_OP, "Light_Buffer" },
  125. { ODD_FIELD_OP, "Odd_Field" },
  126. { OUTPUT_ALPHA_OP, "Output_Alpha" },
  127. { OUTPUT_FILE_NAME_OP, "Output_File_Name" },
  128. { PALETTE_OP, "Palette" },
  129. { PAUSE_WHEN_DONE_OP, "Pause_When_Done" },
  130. { POST_FRAME_CMD_OP, "Post_Frame_Command" },
  131. { POST_FRAME_RET_OP, "Post_Frame_Return" },
  132. { POST_SCENE_CMD_OP, "Post_Scene_Command" },
  133. { POST_SCENE_RET_OP, "Post_Scene_Return" },
  134. { PREVIEW_E_OP, "Preview_End_Size" },
  135. { PREVIEW_S_OP, "Preview_Start_Size" },
  136. { PRE_FRAME_CMD_OP, "Pre_Frame_Command" },
  137. { PRE_FRAME_RET_OP, "Pre_Frame_Return" },
  138. { PRE_SCENE_CMD_OP, "Pre_Scene_command" },
  139. { PRE_SCENE_RET_OP, "Pre_Scene_Return" },
  140. { QUALITY_OP, "Quality" },
  141. { RAD_SWITCH_OP, "Radiosity" },
  142. { REMOVE_BOUNDS_OP, "Remove_Bounds" },
  143. { RENDER_CONSOLE_OP, "Render_Console" },
  144. { RENDER_FILE_OP, "Render_File" },
  145. { SAMPLING_METHOD_OP, "Sampling_Method" },
  146. { SPLIT_UNIONS_OP, "Split_Unions" },
  147. { START_COLUMN_OP, "Start_Column" },
  148. { START_ROW_OP, "Start_Row" },
  149. { STATISTIC_CONSOLE_OP, "Statistic_Console" },
  150. { STATISTIC_FILE_OP, "Statistic_File" },
  151. { SUBSET_END_FRAME_OP, "Subset_End_Frame" },
  152. { SUBSET_START_FRAME_OP, "Subset_Start_Frame" },
  153. { TEST_ABORT_COUNT_OP, "Test_Abort_Count" },
  154. { TEST_ABORT_OP, "Test_Abort" },
  155. { USER_ABORT_CMD_OP, "User_Abort_Command" },
  156. { USER_ABORT_RET_OP, "User_Abort_Return" },
  157. { VERBOSE_OP, "Verbose" },
  158. { VERSION_OP, "Version" },
  159. { VIDEO_MODE_OP, "Video_Mode" },
  160. { VISTA_BUFFER_OP, "Vista_Buffer" },
  161. { WARNING_CONSOLE_OP, "Warning_Console" },
  162. { WARNING_FILE_OP, "Warning_File" },
  163. { WIDTH_OP, "Width" },
  164. { BITS_PER_COLOR_OP, "Bits_Per_Color" },
  165. { BITS_PER_COLOUR_OP, "Bits_Per_Colour" },
  166. { INCLUDE_INI_OP, "Include_Ini" }
  167. };
  168. static char temp_string[3]="\0\0";
  169. static char ret_string[7]="IQUFSA";
  170. /*****************************************************************************
  171. * static functions
  172. ******************************************************************************/
  173. static int matches ( char *v1, char *v2 );
  174. static int istrue ( char *value );
  175. static int isfalse ( char *value );
  176. /*****************************************************************************
  177. *
  178. * FUNCTION
  179. *
  180. * get_ini_value
  181. *
  182. * INPUT
  183. *
  184. * op - the .ini option's index
  185. * libind - if op = LIBRARY_PATH_OP, the library's index
  186. *
  187. * OUTPUT
  188. *
  189. * RETURNS
  190. *
  191. * char * pointing to a static string representation of the
  192. * option's value.
  193. *
  194. * AUTHOR
  195. *
  196. * SCD, 2/95
  197. *
  198. * DESCRIPTION
  199. *
  200. * Returns a static string representation of an option's value.
  201. *
  202. * CHANGES
  203. *
  204. * -
  205. *
  206. ******************************************************************************/
  207. char *get_ini_value(int op, int libind)
  208. {
  209. static char value[128];
  210. value[0] = '\0';
  211. switch (op)
  212. {
  213. case BUF_SIZE_OP:
  214. sprintf(value,"%d", opts.File_Buffer_Size>>10);
  215. return(value);
  216. case BUFFERED_OUTPUT_OP:
  217. return (opts.Options & BUFFERED_OUTPUT ? "On" : "Off");
  218. case CONTINUE_OP:
  219. return (opts.Options & CONTINUE_TRACE ? "On" : "Off");
  220. case DISPLAY_OP:
  221. return (opts.Options & DISPLAY ? "On" : "Off");
  222. case VIDEO_MODE_OP:
  223. sprintf(value,"%c",opts.DisplayFormat);
  224. return(value);
  225. case PALETTE_OP:
  226. sprintf(value,"%c",opts.PaletteOption);
  227. return(value);
  228. case VERBOSE_OP:
  229. return (opts.Options & VERBOSE ? "On" : "Off");
  230. case WIDTH_OP:
  231. sprintf(value,"%d",Frame.Screen_Width);
  232. return(value);
  233. case HEIGHT_OP:
  234. sprintf(value,"%d",Frame.Screen_Height);
  235. return(value);
  236. case FILE_OUTPUT_OP:
  237. return (opts.Options & DISKWRITE ? "On" : "Off");
  238. case FILE_OUTPUT_TYPE_OP:
  239. sprintf(value,"%c",opts.OutputFormat);
  240. return(value);
  241. case PAUSE_WHEN_DONE_OP:
  242. return (opts.Options & PROMPTEXIT ? "On" : "Off");
  243. case INPUT_FILE_NAME_OP:
  244. return opts.Input_File_Name;
  245. case OUTPUT_FILE_NAME_OP:
  246. return opts.Output_File_Name;
  247. case ANTIALIAS_OP:
  248. return (opts.Options & ANTIALIAS ? "On" : "Off");
  249. case ANTIALIAS_THRESH_OP:
  250. sprintf(value,"%g",opts.Antialias_Threshold);
  251. return(value);
  252. case ANTIALIAS_DEPTH_OP:
  253. sprintf(value,"%ld",opts.AntialiasDepth);
  254. return(value);
  255. case JITTER_OP:
  256. return (opts.Options & JITTER ? "On" : "Off");
  257. case JITTER_AMOUNT_OP:
  258. sprintf(value,"%g",opts.JitterScale);
  259. return(value);
  260. case TEST_ABORT_OP:
  261. return (opts.Options & EXITENABLE ? "On" : "Off");
  262. case TEST_ABORT_COUNT_OP:
  263. sprintf(value,"%d",opts.Abort_Test_Counter);
  264. return(value);
  265. case LIBRARY_PATH_OP:
  266. return opts.Library_Paths[libind];
  267. case START_COLUMN_OP:
  268. if (opts.First_Column == -1)
  269. sprintf(value,"%g",opts.First_Column_Percent);
  270. else
  271. sprintf(value,"%d",opts.First_Column);
  272. return(value);
  273. case START_ROW_OP:
  274. if (opts.First_Line == -1)
  275. sprintf(value,"%g",opts.First_Line_Percent);
  276. else
  277. sprintf(value,"%d",opts.First_Line);
  278. return(value);
  279. case END_COLUMN_OP:
  280. if (opts.Last_Column == -1)
  281. sprintf(value,"%g",opts.Last_Column_Percent);
  282. else
  283. sprintf(value,"%d",opts.Last_Column);
  284. return(value);
  285. case END_ROW_OP:
  286. if (opts.Last_Line == -1)
  287. sprintf(value,"%g",opts.Last_Line_Percent);
  288. else
  289. sprintf(value,"%d",opts.Last_Line);
  290. return(value);
  291. case VERSION_OP:
  292. sprintf(value,"%g",opts.Language_Version);
  293. return(value);
  294. case BOUNDING_OP:
  295. return (opts.Use_Slabs ? "On" : "Off");
  296. case BOUNDING_THRESH_OP:
  297. sprintf(value,"%ld",opts.BBox_Threshold);
  298. return(value);
  299. case QUALITY_OP:
  300. sprintf(value,"%d",opts.Quality);
  301. return(value);
  302. case PREVIEW_S_OP:
  303. sprintf(value,"%d",opts.PreviewGridSize_Start);
  304. return value;
  305. case PREVIEW_E_OP:
  306. sprintf(value,"%d",opts.PreviewGridSize_End);
  307. return value;
  308. case CLOCK_OP:
  309. sprintf(value,"%g",opts.FrameSeq.Clock_Value);
  310. return value;
  311. case INITIAL_FRAME_OP:
  312. sprintf(value,"%d",opts.FrameSeq.InitialFrame);
  313. return value;
  314. case INITIAL_CLOCK_OP:
  315. sprintf(value,"%g",opts.FrameSeq.InitialClock);
  316. return value;
  317. case FINAL_FRAME_OP:
  318. sprintf(value,"%d",opts.FrameSeq.FinalFrame);
  319. return value;
  320. case FINAL_CLOCK_OP:
  321. sprintf(value,"%g",opts.FrameSeq.FinalClock);
  322. return value;
  323. case SUBSET_START_FRAME_OP:
  324. sprintf(value,"%d",opts.FrameSeq.SubsetStartFrame);
  325. return value;
  326. case SUBSET_END_FRAME_OP:
  327. sprintf(value,"%d",opts.FrameSeq.SubsetEndFrame);
  328. return value;
  329. case CREATE_INI_OP:
  330. return opts.Ini_Output_File_Name;
  331. case ALL_CONSOLE_OP:
  332. return (Stream_Info[ALL_STREAM].do_console ? "On" : "Off");
  333. case ALL_FILE_OP:
  334. return (Stream_Info[ALL_STREAM].name ? Stream_Info[ALL_STREAM].name : "");
  335. case DEBUG_CONSOLE_OP:
  336. return (Stream_Info[DEBUG_STREAM].do_console ? "On" : "Off");
  337. case DEBUG_FILE_OP:
  338. return (Stream_Info[DEBUG_STREAM].name ? Stream_Info[DEBUG_STREAM].name : "");
  339. case RENDER_CONSOLE_OP:
  340. return (Stream_Info[RENDER_STREAM].do_console ? "On" : "Off");
  341. case RENDER_FILE_OP:
  342. return (Stream_Info[RENDER_STREAM].name ? Stream_Info[RENDER_STREAM].name : "");
  343. case STATISTIC_CONSOLE_OP:
  344. return (Stream_Info[STATISTIC_STREAM].do_console ? "On" : "Off");
  345. case STATISTIC_FILE_OP:
  346. return (Stream_Info[STATISTIC_STREAM].name ? Stream_Info[STATISTIC_STREAM].name : "");
  347. case WARNING_CONSOLE_OP:
  348. return (Stream_Info[WARNING_STREAM].do_console ? "On" : "Off");
  349. case WARNING_FILE_OP:
  350. return (Stream_Info[WARNING_STREAM].name ? Stream_Info[WARNING_STREAM].name : "");
  351. case FATAL_CONSOLE_OP:
  352. return (Stream_Info[FATAL_STREAM].do_console ? "On" : "Off");
  353. case FATAL_FILE_OP:
  354. return (Stream_Info[FATAL_STREAM].name ? Stream_Info[FATAL_STREAM].name : "");
  355. case RAD_SWITCH_OP:
  356. return (opts.Options & RADIOSITY ? "On" : "Off");
  357. case HIST_SIZE_OP:
  358. sprintf (value, "%d.%d", opts.histogram_x, opts.histogram_y) ;
  359. return (value) ;
  360. case HIST_TYPE_OP:
  361. switch (opts.histogram_type)
  362. {
  363. case CSV :
  364. return ("C ; CSV") ;
  365. case SYS :
  366. return ("S ; SYS") ;
  367. case PPM :
  368. return ("P ; PPM") ;
  369. case TARGA :
  370. return ("T ; TARGA") ;
  371. case PNG :
  372. return ("N ; PNG") ;
  373. case NONE :
  374. return ("X ; NONE") ;
  375. }
  376. return ("X ; [UNKNOWN VALUE PASSED]") ;
  377. case HIST_NAME_OP:
  378. return (opts.Histogram_File_Name) ;
  379. case VISTA_BUFFER_OP:
  380. return ((opts.Options & USE_VISTA_BUFFER) ? "On" : "Off");
  381. case LIGHT_BUFFER_OP:
  382. return ((opts.Options & USE_LIGHT_BUFFER) ? "On" : "Off");
  383. case DRAW_VISTAS_OP:
  384. return ((opts.Options & USE_VISTA_DRAW) ? "On" : "Off");
  385. case SPLIT_UNIONS_OP:
  386. return ((opts.Options & SPLIT_UNION) ? "On" : "Off");
  387. case REMOVE_BOUNDS_OP:
  388. return ((opts.Options & REMOVE_BOUNDS) ? "On" : "Off");
  389. case CYCLIC_ANIMATION_OP:
  390. return ((opts.Options & CYCLIC_ANIMATION) ? "On" : "Off");
  391. case PRE_SCENE_CMD_OP:
  392. return opts.Shellouts[PRE_SCENE_SHL].Command;
  393. case PRE_FRAME_CMD_OP:
  394. return opts.Shellouts[PRE_FRAME_SHL].Command;
  395. case POST_FRAME_CMD_OP:
  396. return opts.Shellouts[POST_FRAME_SHL].Command;
  397. case POST_SCENE_CMD_OP:
  398. return opts.Shellouts[POST_SCENE_SHL].Command;
  399. case USER_ABORT_CMD_OP:
  400. return opts.Shellouts[USER_ABORT_SHL].Command;
  401. case FATAL_ERROR_CMD_OP:
  402. return opts.Shellouts[FATAL_SHL].Command;
  403. case PRE_SCENE_RET_OP:
  404. temp_string[0]=(opts.Shellouts[PRE_SCENE_SHL].Inverse)?'!':' ';
  405. temp_string[1]=ret_string[opts.Shellouts[PRE_SCENE_SHL].Ret];
  406. return temp_string;
  407. case PRE_FRAME_RET_OP:
  408. temp_string[0]=(opts.Shellouts[PRE_FRAME_SHL].Inverse)?'!':' ';
  409. temp_string[1]=ret_string[opts.Shellouts[PRE_FRAME_SHL].Ret];
  410. return temp_string;
  411. case POST_FRAME_RET_OP:
  412. temp_string[0]=(opts.Shellouts[POST_FRAME_SHL].Inverse)?'!':' ';
  413. temp_string[1]=ret_string[opts.Shellouts[POST_FRAME_SHL].Ret];
  414. return temp_string;
  415. case POST_SCENE_RET_OP:
  416. temp_string[0]=(opts.Shellouts[POST_SCENE_SHL].Inverse)?'!':' ';
  417. temp_string[1]=ret_string[opts.Shellouts[POST_SCENE_SHL].Ret];
  418. return temp_string;
  419. case USER_ABORT_RET_OP:
  420. temp_string[0]=(opts.Shellouts[USER_ABORT_SHL].Inverse)?'!':' ';
  421. temp_string[1]=ret_string[opts.Shellouts[USER_ABORT_SHL].Ret];
  422. return temp_string;
  423. case FATAL_ERROR_RET_OP:
  424. temp_string[0]=(opts.Shellouts[FATAL_SHL].Inverse)?'!':' ';
  425. temp_string[1]=ret_string[opts.Shellouts[FATAL_SHL].Ret];
  426. return temp_string;
  427. case OUTPUT_ALPHA_OP:
  428. return ((opts.Options & OUTPUT_ALPHA) ? "On" : "Off");
  429. case FIELD_RENDER_OP:
  430. return (opts.FrameSeq.Field_Render_Flag ? "On" : "Off");
  431. case ODD_FIELD_OP:
  432. return (opts.FrameSeq.Odd_Field_Flag ? "On" : "Off");
  433. case SAMPLING_METHOD_OP:
  434. sprintf(value,"%d",opts.Tracing_Method);
  435. return value;
  436. case BITS_PER_COLOR_OP:
  437. case BITS_PER_COLOUR_OP:
  438. sprintf(value,"%d",opts.OutputQuality);
  439. return value;
  440. case DISPLAY_GAMMA_OP:
  441. sprintf(value,"%g",opts.DisplayGamma);
  442. return value;
  443. case INCLUDE_INI_OP:
  444. value[0] = '\0';
  445. return value;
  446. default:
  447. Error("Unknown INI option in Write_INI.");
  448. }
  449. return(value);
  450. }
  451. /*****************************************************************************
  452. *
  453. * FUNCTION
  454. *
  455. * parse_switch
  456. *
  457. * INPUT
  458. *
  459. * OUTPUT
  460. *
  461. * RETURNS
  462. *
  463. * AUTHOR
  464. *
  465. * POV-Ray Team
  466. *
  467. * DESCRIPTION
  468. *
  469. * Parses a traditional POV-Ray command-line switch that starts
  470. * with + or -. Whenever it seemed feasible, calls process_variable
  471. * to perform the function rather than doing so itself. Although this
  472. * requires another pass through a switch{case, case...}, it insures
  473. * that command-line switches and variable=value options get treated
  474. * identically.
  475. *
  476. * CHANGES
  477. *
  478. * -
  479. *
  480. * Sep 1994 : Added options for union splitting, vista/light buffer. [DB]
  481. * Jan 1995 : Added options for histogram grid. [CJC]
  482. * Feb 1995 : Added options for console/file redirection and .INI writing [SCD]
  483. *
  484. ******************************************************************************/
  485. void parse_switch (char *Option_String)
  486. {
  487. int i;
  488. unsigned long Add_Option;
  489. unsigned long Option_Number;
  490. long longval;
  491. DBL floatval;
  492. if (*(Option_String++) == '-')
  493. {
  494. Add_Option = FALSE;
  495. }
  496. else
  497. {
  498. Add_Option = TRUE;
  499. }
  500. Option_Number = 0;
  501. switch (*Option_String)
  502. {
  503. case '?':
  504. if (Option_String[1] == '\0')
  505. {
  506. Usage(0, TRUE);
  507. }
  508. else
  509. {
  510. sscanf (&Option_String[1], "%d", &i);
  511. if ((i >= 0) && (i <= MAX_HELP_PAGE))
  512. {
  513. Usage(i, TRUE);
  514. }
  515. else
  516. {
  517. Usage(0, TRUE);
  518. }
  519. }
  520. break;
  521. case '@':
  522. Warning(0.0,"The +@ switch no longer supported. Use +GS.\n");
  523. break;
  524. case 'A':
  525. case 'a':
  526. switch (Option_String[1])
  527. {
  528. case 'm':
  529. case 'M':
  530. switch (Option_String[2])
  531. {
  532. case '1':
  533. opts.Tracing_Method = 1;
  534. break;
  535. case '2':
  536. opts.Tracing_Method = 2;
  537. break;
  538. default:
  539. Warning(0.0, "Unknown antialiasing method. Standard method used.\n");
  540. opts.Tracing_Method = 1;
  541. }
  542. break;
  543. default:
  544. Option_Number = ANTIALIAS;
  545. if (sscanf (&Option_String[1], DBL_FORMAT_STRING, &floatval) != SCANF_EOF)
  546. {
  547. opts.Antialias_Threshold = floatval;
  548. }
  549. }
  550. break;
  551. case 'B':
  552. case 'b':
  553. process_variable(BUF_SIZE_OP, &Option_String[1]);
  554. if (opts.File_Buffer_Size > 0)
  555. {
  556. Option_Number = BUFFERED_OUTPUT;
  557. }
  558. break;
  559. case 'C':
  560. case 'c':
  561. Option_Number = CONTINUE_TRACE;
  562. break;
  563. case 'D':
  564. case 'd':
  565. Option_Number = DISPLAY;
  566. if (Option_String[1] != '\0')
  567. {
  568. opts.DisplayFormat = (char)toupper(Option_String[1]);
  569. }
  570. if (Option_String[1] != '\0' && Option_String[2] != '\0')
  571. {
  572. opts.PaletteOption = (char)toupper(Option_String[2]);
  573. }
  574. break;
  575. case 'E':
  576. case 'e':
  577. switch (Option_String[1])
  578. {
  579. case 'c':
  580. case 'C':
  581. process_variable(END_COLUMN_OP,&Option_String[2]);
  582. break;
  583. case 'f':
  584. case 'F':
  585. if(isdigit((int)Option_String[2])) /* tw */
  586. process_variable(SUBSET_END_FRAME_OP, &Option_String[2]);
  587. break;
  588. case 'r':
  589. case 'R':
  590. process_variable(END_ROW_OP,&Option_String[2]);
  591. break;
  592. case 'p': /* Mosaic Preview Grid Size - End */
  593. case 'P':
  594. process_variable(PREVIEW_E_OP,&Option_String[2]);
  595. break;
  596. default:
  597. process_variable(END_ROW_OP,&Option_String[1]);
  598. }
  599. break;
  600. case 'F':
  601. case 'f':
  602. Option_Number = DISKWRITE;
  603. if (Option_String[1] != '\0')
  604. {
  605. opts.OutputFormat = (char)tolower(Option_String[1]);
  606. }
  607. if (sscanf(&Option_String[2], "%d", &opts.OutputQuality) != 1)
  608. {
  609. opts.OutputQuality = 8;
  610. }
  611. break;
  612. /* Console/file redirection, .INI dump option - [SCD 2/95] */
  613. case 'G':
  614. case 'g':
  615. switch (Option_String[1])
  616. {
  617. case 'a': /* All */
  618. case 'A':
  619. process_variable(ALL_CONSOLE_OP,Add_Option ? "On" : "Off");
  620. process_variable(ALL_FILE_OP,&Option_String[2]);
  621. break;
  622. case 'd': /* DebugInfo */
  623. case 'D':
  624. process_variable(DEBUG_CONSOLE_OP,Add_Option ? "On" : "Off");
  625. process_variable(DEBUG_FILE_OP,&Option_String[2]);
  626. break;
  627. case 'f': /* Fatal */
  628. case 'F':
  629. process_variable(FATAL_CONSOLE_OP,Add_Option ? "On" : "Off");
  630. process_variable(FATAL_FILE_OP,&Option_String[2]);
  631. break;
  632. case 'i': /* Create .INI containing all settings */
  633. case 'I':
  634. process_variable(CREATE_INI_OP,&Option_String[2]);
  635. break;
  636. case 'r': /* RenderInfo */
  637. case 'R':
  638. process_variable(RENDER_CONSOLE_OP,Add_Option ? "On" : "Off");
  639. process_variable(RENDER_FILE_OP,&Option_String[2]);
  640. break;
  641. case 's': /* Statistics */
  642. case 'S':
  643. process_variable(STATISTIC_CONSOLE_OP,Add_Option ? "On" : "Off");
  644. process_variable(STATISTIC_FILE_OP,&Option_String[2]);
  645. break;
  646. case 'w': /* Warning */
  647. case 'W':
  648. process_variable(WARNING_CONSOLE_OP,Add_Option ? "On" : "Off");
  649. process_variable(WARNING_FILE_OP,&Option_String[2]);
  650. break;
  651. }
  652. break;
  653. case 'H':
  654. case 'h':
  655. if (Help_Available)
  656. {
  657. if (Option_String[1] == '\0')
  658. {
  659. Usage(0, TRUE);
  660. }
  661. else
  662. {
  663. sscanf (&Option_String[1], "%d", &Frame.Screen_Height);
  664. if ((Frame.Screen_Height >= 0) && (Frame.Screen_Height <= MAX_HELP_PAGE))
  665. {
  666. Usage(Frame.Screen_Height, TRUE);
  667. }
  668. }
  669. }
  670. else
  671. {
  672. if (!isdigit ((int)Option_String [1])) /* tw */
  673. {
  674. switch (Option_String [1])
  675. {
  676. case 'n': /* Histogram name */
  677. case 'N':
  678. process_variable(HIST_NAME_OP,&Option_String[2]);
  679. break ;
  680. case 's': /* Histogram size */
  681. case 'S':
  682. process_variable(HIST_SIZE_OP,&Option_String[2]);
  683. break ;
  684. case 't': /* Histogram type */
  685. case 'T':
  686. process_variable(HIST_TYPE_OP,&Option_String[2]);
  687. break ;
  688. }
  689. }
  690. else
  691. {
  692. sscanf (&Option_String[1], "%d", &Frame.Screen_Height);
  693. }
  694. }
  695. break;
  696. case 'I':
  697. case 'i':
  698. if (Option_String[1] == '\0')
  699. {
  700. inflag = TRUE;
  701. }
  702. else
  703. {
  704. process_variable(INPUT_FILE_NAME_OP, &Option_String[1]);
  705. }
  706. break;
  707. case 'J':
  708. case 'j':
  709. Option_Number = JITTER;
  710. if (sscanf (&Option_String[1], DBL_FORMAT_STRING, &floatval) != SCANF_EOF)
  711. {
  712. opts.JitterScale = floatval;
  713. }
  714. if (opts.JitterScale <= 0.0)
  715. {
  716. Add_Option = FALSE;
  717. }
  718. break;
  719. case 'K':
  720. case 'k':
  721. /* Animation-type clock specification */
  722. switch(Option_String[1])
  723. {
  724. case 'c':
  725. case 'C':
  726. Option_Number = CYCLIC_ANIMATION;
  727. break;
  728. case 'i':
  729. case 'I':
  730. process_variable(INITIAL_CLOCK_OP, &Option_String[2]);
  731. break;
  732. case 'f':
  733. case 'F':
  734. /* Animation-type clock specification */
  735. switch(Option_String[2])
  736. {
  737. case 'i':
  738. case 'I':
  739. process_variable(INITIAL_FRAME_OP, &Option_String[3]);
  740. break;
  741. case 'f':
  742. case 'F':
  743. process_variable(FINAL_FRAME_OP, &Option_String[3]);
  744. break;
  745. default:
  746. process_variable(FINAL_CLOCK_OP, &Option_String[2]);
  747. break;
  748. }
  749. break;
  750. default:
  751. /* Standard clock specification */
  752. process_variable(CLOCK_OP,&Option_String[1]);
  753. break;
  754. }
  755. break;
  756. case 'L':
  757. case 'l':
  758. process_variable(LIBRARY_PATH_OP,&Option_String[1]);
  759. break;
  760. case 'M': /* Switch used so other max values can be inserted easily */
  761. case 'm':
  762. switch (Option_String[1])
  763. {
  764. case 's': /* Max Symbols */
  765. case 'S':
  766. Warning(0.0,"+MS or -MS switch no longer needed.\n");
  767. break;
  768. case 'v': /* Max Version */
  769. case 'V':
  770. sscanf (&Option_String[2], DBL_FORMAT_STRING, &opts.Language_Version);
  771. break;
  772. case 'b': /* Min Bounded */
  773. case 'B':
  774. if (sscanf (&Option_String[2], "%ld", &longval) != SCANF_EOF)
  775. {
  776. opts.BBox_Threshold=longval;
  777. }
  778. opts.Use_Slabs = Add_Option;
  779. break;
  780. default:
  781. break;
  782. }
  783. break;
  784. /* "N" option flag is used by networking (multi-processor) options.
  785. case 'N':
  786. case 'n':
  787. break;
  788. */
  789. case 'O':
  790. case 'o':
  791. if (Option_String[1] == '\0')
  792. {
  793. outflag = TRUE;
  794. }
  795. else
  796. {
  797. process_variable(OUTPUT_FILE_NAME_OP, &Option_String[1]);
  798. }
  799. break;
  800. case 'P':
  801. case 'p':
  802. Option_Number = PROMPTEXIT;
  803. break;
  804. case 'Q':
  805. case 'q':
  806. switch(Option_String[1])
  807. {
  808. case 'r':
  809. case 'R':
  810. Option_Number = RADIOSITY;
  811. break;
  812. case '0':
  813. case '1':
  814. case '2':
  815. case '3':
  816. case '4':
  817. case '5':
  818. case '6':
  819. case '7':
  820. case '8':
  821. case '9':
  822. process_variable(QUALITY_OP,&Option_String[1]);
  823. break;
  824. default:
  825. break;
  826. }
  827. break;
  828. case 'R':
  829. case 'r':
  830. process_variable(ANTIALIAS_DEPTH_OP,&Option_String[1]);
  831. break;
  832. case 'S':
  833. case 's':
  834. switch (Option_String[1])
  835. {
  836. case 'c':
  837. case 'C':
  838. process_variable(START_COLUMN_OP,&Option_String[2]);
  839. break;
  840. case 'r':
  841. case 'R':
  842. process_variable(START_ROW_OP,&Option_String[2]);
  843. break;
  844. case 'f':
  845. case 'F':
  846. process_variable(SUBSET_START_FRAME_OP, &Option_String[2]);
  847. break;
  848. case 'p': /* Mosaic Preview Grid Size - Start */
  849. case 'P':
  850. process_variable(PREVIEW_S_OP,&Option_String[2]);
  851. break;
  852. /* Split unions option. [DB 9/94] */
  853. case 'U':
  854. case 'u':
  855. Option_Number = SPLIT_UNION;
  856. break;
  857. default:
  858. process_variable(START_ROW_OP,&Option_String[1]);
  859. }
  860. break;
  861. /* Read vista/light buffer options. [DB 9/94] */
  862. case 'U':
  863. case 'u':
  864. switch (Option_String[1])
  865. {
  866. case 'l':
  867. case 'L':
  868. Option_Number = USE_LIGHT_BUFFER;
  869. break;
  870. case 'd':
  871. case 'D':
  872. Option_Number = USE_VISTA_DRAW;
  873. break;
  874. case 'r':
  875. case 'R':
  876. Option_Number = REMOVE_BOUNDS;
  877. break;
  878. case 'v':
  879. case 'V':
  880. Option_Number = USE_VISTA_BUFFER;
  881. break;
  882. case 'a':
  883. case 'A':
  884. Option_Number = OUTPUT_ALPHA;
  885. break;
  886. case 'f':
  887. case 'F':
  888. process_variable(FIELD_RENDER_OP, Add_Option ? "True" : "False");
  889. break;
  890. case 'o':
  891. case 'O':
  892. process_variable(ODD_FIELD_OP, Add_Option ? "True" : "False");
  893. break;
  894. }
  895. break;
  896. case 'V':
  897. case 'v':
  898. Option_Number = VERBOSE;
  899. break;
  900. case 'W':
  901. case 'w':
  902. sscanf (&Option_String[1], "%d", &Frame.Screen_Width);
  903. break;
  904. case 'X':
  905. case 'x':
  906. Option_Number = EXITENABLE;
  907. sscanf (&Option_String[1], "%d", &Abort_Test_Every);
  908. opts.Abort_Test_Counter = Abort_Test_Every;
  909. break;
  910. default:
  911. Warning (0.0,"Invalid option: %s.\n", --Option_String);
  912. }
  913. if (Option_Number != 0)
  914. {
  915. if (Add_Option)
  916. {
  917. opts.Options |= Option_Number;
  918. }
  919. else
  920. {
  921. opts.Options &= ~Option_Number;
  922. }
  923. }
  924. }
  925. /*****************************************************************************
  926. *
  927. * FUNCTION
  928. *
  929. * process_variable
  930. *
  931. * INPUT
  932. *
  933. * OUTPUT
  934. *
  935. * RETURNS
  936. *
  937. * AUTHOR
  938. *
  939. * POV-Ray Team
  940. *
  941. * DESCRIPTION
  942. *
  943. * Given a token number representing an option variable and a string
  944. * that is the value to set, set one option. If its just an on/off
  945. * switch that takes a boolean value then just set Option_Number and
  946. * break. Otherwise process the value and return.
  947. *
  948. * CHANGES
  949. *
  950. * -
  951. *
  952. ******************************************************************************/
  953. void process_variable(TOKEN variable,char *value)
  954. {
  955. int i;
  956. long longval;
  957. unsigned int Option_Number = 0;
  958. DBL floatval;
  959. switch (variable)
  960. {
  961. case BUF_SIZE_OP:
  962. if (sscanf (value, "%d", &opts.File_Buffer_Size) != SCANF_EOF)
  963. {
  964. opts.File_Buffer_Size *= 1024;
  965. if (opts.File_Buffer_Size > MAX_BUFSIZE)
  966. opts.File_Buffer_Size = MAX_BUFSIZE;
  967. /* If 0 then no buffer, other low values use system default MIN */
  968. if ((opts.File_Buffer_Size > 0) && (opts.File_Buffer_Size < BUFSIZ))
  969. {
  970. opts.File_Buffer_Size = BUFSIZ;
  971. }
  972. if (opts.File_Buffer_Size <= 0)
  973. {
  974. opts.Options &= ~BUFFERED_OUTPUT;
  975. }
  976. }
  977. return;
  978. case BUFFERED_OUTPUT_OP:
  979. Option_Number = BUFFERED_OUTPUT;
  980. break;
  981. case CONTINUE_OP:
  982. Option_Number = CONTINUE_TRACE;
  983. break;
  984. case DISPLAY_OP:
  985. Option_Number = DISPLAY;
  986. break;
  987. case VIDEO_MODE_OP:
  988. opts.DisplayFormat = (char)toupper(value[0]);
  989. return;
  990. case PALETTE_OP:
  991. opts.PaletteOption = (char)toupper(value[0]);
  992. return;
  993. case VERBOSE_OP:
  994. Option_Number = VERBOSE;
  995. break;
  996. case WIDTH_OP:
  997. Frame.Screen_Width = atoi(value);
  998. return;
  999. case HEIGHT_OP:
  1000. Frame.Screen_Height = atoi(value);
  1001. return;
  1002. case FILE_OUTPUT_OP:
  1003. Option_Number = DISKWRITE;
  1004. break;
  1005. case FILE_OUTPUT_TYPE_OP:
  1006. opts.OutputFormat = (char)tolower(value[0]);
  1007. return;
  1008. case PAUSE_WHEN_DONE_OP:
  1009. Option_Number = PROMPTEXIT;
  1010. break;
  1011. case INPUT_FILE_NAME_OP:
  1012. if (!strcmp(value, "-") || !strcmp(value, "stdin"))
  1013. {
  1014. strcpy (opts.Input_File_Name, "stdin");
  1015. opts.Options |= FROM_STDIN;
  1016. }
  1017. else
  1018. {
  1019. strncpy (opts.Input_File_Name, value, FILE_NAME_LENGTH);
  1020. }
  1021. return;
  1022. case OUTPUT_FILE_NAME_OP:
  1023. if (!strcmp(value, "-") || !strcmp(value, "stdout"))
  1024. {
  1025. strcpy (opts.Output_File_Name, "stdout");
  1026. opts.Options |= TO_STDOUT;
  1027. }
  1028. else
  1029. {
  1030. strncpy (opts.Output_File_Name, value, FILE_NAME_LENGTH);
  1031. }
  1032. return;
  1033. case ANTIALIAS_OP:
  1034. Option_Number = ANTIALIAS;
  1035. break;
  1036. case ANTIALIAS_THRESH_OP:
  1037. if (sscanf (value, DBL_FORMAT_STRING, &floatval) != SCANF_EOF)
  1038. opts.Antialias_Threshold = floatval;
  1039. return;
  1040. case ANTIALIAS_DEPTH_OP:
  1041. if (sscanf (value, "%ld", &longval) != SCANF_EOF)
  1042. opts.AntialiasDepth = longval;
  1043. if (opts.AntialiasDepth < 1)
  1044. opts.AntialiasDepth = 1;
  1045. if (opts.AntialiasDepth > 9)
  1046. opts.AntialiasDepth = 9;
  1047. return;
  1048. case JITTER_OP:
  1049. Option_Number = JITTER;
  1050. break;
  1051. case JITTER_AMOUNT_OP:
  1052. if (sscanf (value, DBL_FORMAT_STRING, &floatval) != SCANF_EOF)
  1053. opts.JitterScale = floatval;
  1054. if (opts.JitterScale<=0.0)
  1055. opts.Options &= ~JITTER;
  1056. return;
  1057. case TEST_ABORT_OP:
  1058. Option_Number = EXITENABLE;
  1059. break;
  1060. case TEST_ABORT_COUNT_OP:
  1061. sscanf (value, "%d", &Abort_Test_Every);
  1062. opts.Abort_Test_Counter = Abort_Test_Every;
  1063. break;
  1064. case LIBRARY_PATH_OP:
  1065. if (opts.Library_Path_Index >= MAX_LIBRARIES)
  1066. Error ("Too many library directories specified.");
  1067. for (i = 0; i < opts.Library_Path_Index; i++)
  1068. if (strcmp(value,opts.Library_Paths[i])==0) return;
  1069. opts.Library_Paths[opts.Library_Path_Index] = (char *)POV_MALLOC(strlen(value)+1,
  1070. "library paths");
  1071. strcpy (opts.Library_Paths [opts.Library_Path_Index], value);
  1072. opts.Library_Path_Index++;
  1073. return;
  1074. case START_COLUMN_OP:
  1075. if (sscanf (value, DBL_FORMAT_STRING, &floatval) != SCANF_EOF)
  1076. { /* tw */
  1077. if(floatval > 0.0 && floatval < 1.0)
  1078. {
  1079. opts.First_Column = -1;
  1080. opts.First_Column_Percent = floatval;
  1081. }
  1082. else
  1083. opts.First_Column = ((int) floatval);
  1084. /* The above used to have -1 but it messed up Write_INI_File.
  1085. * Moved -1 fudge to fix_up_rendering_window
  1086. */
  1087. } /* tw */
  1088. return;
  1089. case START_ROW_OP:
  1090. if (sscanf (value, DBL_FORMAT_STRING, &floatval) != SCANF_EOF)
  1091. { /* tw */
  1092. if(floatval > 0.0 && floatval < 1.0)
  1093. {
  1094. opts.First_Line = -1;
  1095. opts.First_Line_Percent = floatval;
  1096. }
  1097. else
  1098. opts.First_Line = ((int) floatval);
  1099. /* The above used to have -1 but it messed up Write_INI_File
  1100. * Moved -1 fudge to fix_up_rendering_window
  1101. */
  1102. } /* tw */
  1103. return;
  1104. case END_COLUMN_OP:
  1105. { /* tw */
  1106. if (sscanf (value, DBL_FORMAT_STRING, &floatval) != SCANF_EOF)
  1107. if(floatval > 0.0 && floatval <= 1.0)
  1108. {
  1109. opts.Last_Column = -1;
  1110. opts.Last_Column_Percent = floatval;
  1111. }
  1112. else
  1113. opts.Last_Column = (int) floatval;
  1114. } /* tw */
  1115. return;
  1116. case END_ROW_OP:
  1117. { /* tw */
  1118. if (sscanf (value, DBL_FORMAT_STRING, &floatval) != SCANF_EOF)
  1119. if(floatval > 0.0 && floatval <= 1.0)
  1120. {
  1121. opts.Last_Line = -1;
  1122. opts.Last_Line_Percent = floatval;
  1123. }
  1124. else
  1125. opts.Last_Line = (int) floatval;
  1126. } /* tw */
  1127. return;
  1128. case VERSION_OP:
  1129. if (sscanf (value, DBL_FORMAT_STRING, &floatval) != SCANF_EOF)
  1130. opts.Language_Version = floatval;
  1131. return;
  1132. case BOUNDING_OP:
  1133. opts.Use_Slabs = istrue(value);
  1134. return;
  1135. case BOUNDING_THRESH_OP:
  1136. opts.BBox_Threshold = atoi(value);
  1137. return;
  1138. case QUALITY_OP:
  1139. opts.Quality = atoi(value);
  1140. /* Emit a warning about the "radiosity" quality levels for
  1141. * now. We can get rid of this some time in the future.
  1142. */
  1143. if ((opts.Quality == 10) || (opts.Quality == 11))
  1144. {
  1145. Warning(0.0, "Quality settings 10 and 11 are no longer valid.\n"
  1146. "Use +QR if you need radiosity.\n");
  1147. opts.Quality = 9;
  1148. }
  1149. else if ((opts.Quality < 0) || (opts.Quality > 9))
  1150. {
  1151. Error("Illegal Quality setting.");
  1152. }
  1153. opts.Quality_Flags = Quality_Values[opts.Quality];
  1154. return;
  1155. case CLOCK_OP:
  1156. if(sscanf (value, DBL_FORMAT_STRING, &floatval) != SCANF_EOF)
  1157. {
  1158. opts.FrameSeq.Clock_Value = floatval;
  1159. }
  1160. return;
  1161. case INITIAL_FRAME_OP:
  1162. if(sscanf(value, "%ld", &longval)!=SCANF_EOF)
  1163. {
  1164. opts.FrameSeq.InitialFrame=longval;
  1165. }
  1166. return;
  1167. case INITIAL_CLOCK_OP:
  1168. if(sscanf(value, DBL_FORMAT_STRING, &floatval)!=SCANF_EOF)
  1169. {
  1170. opts.FrameSeq.InitialClock=floatval;
  1171. }
  1172. return;
  1173. case FINAL_FRAME_OP:
  1174. if(sscanf(value, "%ld", &longval)!=SCANF_EOF)
  1175. {
  1176. opts.FrameSeq.FinalFrame=longval;
  1177. }
  1178. return;
  1179. case FINAL_CLOCK_OP:
  1180. if(sscanf(value, DBL_FORMAT_STRING, &floatval)!=SCANF_EOF)
  1181. {
  1182. opts.FrameSeq.FinalClock=floatval;
  1183. }
  1184. return;
  1185. case SUBSET_START_FRAME_OP:
  1186. if (sscanf (value, DBL_FORMAT_STRING, &floatval) != SCANF_EOF)
  1187. {
  1188. if(floatval > 0.0 && floatval < 1.0)
  1189. opts.FrameSeq.SubsetStartPercent=floatval;
  1190. else
  1191. opts.FrameSeq.SubsetStartFrame=(int)floatval;
  1192. }
  1193. return;
  1194. case SUBSET_END_FRAME_OP:
  1195. if (sscanf (value, DBL_FORMAT_STRING, &floatval) != SCANF_EOF)
  1196. {
  1197. if(floatval > 0.0 && floatval < 1.0)
  1198. opts.FrameSeq.SubsetEndPercent=floatval;
  1199. else
  1200. opts.FrameSeq.SubsetEndFrame=(int)floatval;
  1201. }
  1202. return;
  1203. case PREVIEW_S_OP:
  1204. opts.PreviewGridSize_Start = atoi(value);
  1205. return;
  1206. case PREVIEW_E_OP:
  1207. opts.PreviewGridSize_End = atoi(value);
  1208. return;
  1209. case CREATE_INI_OP:
  1210. strcpy(opts.Ini_Output_File_Name,value);
  1211. return;
  1212. case ALL_CONSOLE_OP:
  1213. Stream_Info[ALL_STREAM].do_console =
  1214. Stream_Info[WARNING_STREAM].do_console =
  1215. Stream_Info[STATISTIC_STREAM].do_console =
  1216. Stream_Info[RENDER_STREAM].do_console =
  1217. Stream_Info[FATAL_STREAM].do_console =
  1218. Stream_Info[DEBUG_STREAM].do_console = istrue(value);
  1219. return;
  1220. case ALL_FILE_OP:
  1221. Do_Stream_Option(ALL_STREAM,value);
  1222. return;
  1223. case DEBUG_CONSOLE_OP:
  1224. Stream_Info[DEBUG_STREAM].do_console = istrue(value);
  1225. return;
  1226. case DEBUG_FILE_OP:
  1227. Do_Stream_Option(DEBUG_STREAM,value);
  1228. return;
  1229. case FATAL_CONSOLE_OP:
  1230. Stream_Info[FATAL_STREAM].do_console = istrue(value);
  1231. return;
  1232. case FATAL_FILE_OP:
  1233. Do_Stream_Option(FATAL_STREAM,value);
  1234. return;
  1235. case RENDER_CONSOLE_OP:
  1236. Stream_Info[RENDER_STREAM].do_console = istrue(value);
  1237. return;
  1238. case RENDER_FILE_OP:
  1239. Do_Stream_Option(RENDER_STREAM,value);
  1240. return;
  1241. case STATISTIC_CONSOLE_OP:
  1242. Stream_Info[STATISTIC_STREAM].do_console = istrue(value);
  1243. return;
  1244. case STATISTIC_FILE_OP:
  1245. Do_Stream_Option(STATISTIC_STREAM,value);
  1246. return;
  1247. case WARNING_CONSOLE_OP:
  1248. Stream_Info[WARNING_STREAM].do_console = istrue(value);
  1249. return;
  1250. case WARNING_FILE_OP:
  1251. Do_Stream_Option(WARNING_STREAM,value);
  1252. return;
  1253. case RAD_SWITCH_OP:
  1254. Option_Number = RADIOSITY;
  1255. break;
  1256. case HIST_SIZE_OP:
  1257. if (sscanf (value, "%d.%d", &opts.histogram_x, &opts.histogram_y) == SCANF_EOF)
  1258. {
  1259. Warning (0.0, "Error occurred scanning histogram grid size '%s'.\n", value) ;
  1260. opts.histogram_on = FALSE ;
  1261. }
  1262. break ;
  1263. case HIST_TYPE_OP:
  1264. #if PRECISION_TIMER_AVAILABLE
  1265. {
  1266. char *def_ext = NULL;
  1267. switch (*value)
  1268. {
  1269. case 'C' :
  1270. case 'c' :
  1271. opts.histogram_on = TRUE ;
  1272. opts.histogram_type = CSV ;
  1273. def_ext = ".csv";
  1274. break ;
  1275. case 'S' :
  1276. case 's' :
  1277. opts.histogram_on = TRUE ;
  1278. opts.histogram_type = SYS ;
  1279. Histogram_File_Handle = GET_SYS_FILE_HANDLE () ;
  1280. def_ext = SYS_DEF_EXT;
  1281. break ;
  1282. case 'P' :
  1283. case 'p' :
  1284. opts.histogram_on = TRUE ;
  1285. opts.histogram_type = PPM ;
  1286. Histogram_File_Handle = Get_PPM_File_Handle () ;
  1287. def_ext = ".ppm";
  1288. break ;
  1289. case 'T' :
  1290. case 't' :
  1291. opts.histogram_on = TRUE ;
  1292. opts.histogram_type = TARGA ;
  1293. Histogram_File_Handle = Get_Targa_File_Handle () ;
  1294. def_ext = ".tga";
  1295. break ;
  1296. case 'n':
  1297. case 'N':
  1298. opts.histogram_on = TRUE ;
  1299. opts.histogram_type = PNG ;
  1300. Histogram_File_Handle = Get_Png_File_Handle () ;
  1301. def_ext = ".png";
  1302. break ;
  1303. case 'x':
  1304. case 'X':
  1305. opts.histogram_on = FALSE ;
  1306. break ;
  1307. default :
  1308. Warning (0.0, "Unknown histogram output type '%c'.\n", *value) ;
  1309. opts.histogram_on = FALSE ;
  1310. break ;
  1311. }
  1312. /* Process the histogram file name now, if it hasn't
  1313. * yet been specified, and in case it isn't set later.
  1314. */
  1315. if (opts.histogram_on && opts.Histogram_File_Name[0] == '\0')
  1316. {
  1317. sprintf(opts.Histogram_File_Name, "histgram%s", def_ext);
  1318. }
  1319. }
  1320. #else /* !PRECISION_TIMER_AVAILABLE */
  1321. if (*value != 'x' && *value != 'X')
  1322. Warning(0.0,"Histogram output unavailable in this compile of POV-Ray");
  1323. opts.histogram_on = FALSE;
  1324. #endif /* PRECISION_TIMER_AVAILABLE */
  1325. break ;
  1326. case HIST_NAME_OP:
  1327. if (opts.histogram_on && value[0] == '\0')
  1328. {
  1329. char *def_ext = NULL;
  1330. switch (opts.histogram_type)
  1331. {
  1332. case CSV: def_ext = ".csv"; break;
  1333. case TARGA: def_ext = ".tga"; break;
  1334. case PNG: def_ext = ".png"; break;
  1335. case PPM: def_ext = ".ppm"; break;
  1336. case SYS: def_ext = SYS_DEF_EXT; break;
  1337. case NONE: def_ext = ""; break; /* To quiet warnings */
  1338. }
  1339. sprintf(opts.Histogram_File_Name, "histgram%s", def_ext);
  1340. }
  1341. else
  1342. {
  1343. strncpy (opts.Histogram_File_Name, value, FILE_NAME_LENGTH);
  1344. }
  1345. break ;
  1346. case VISTA_BUFFER_OP:
  1347. Option_Number = USE_VISTA_BUFFER;
  1348. break;
  1349. case LIGHT_BUFFER_OP:
  1350. Option_Number = USE_LIGHT_BUFFER;
  1351. break;
  1352. case DRAW_VISTAS_OP:
  1353. Option_Number = USE_VISTA_DRAW;
  1354. break;
  1355. case SPLIT_UNIONS_OP:
  1356. Option_Number = SPLIT_UNION;
  1357. break;
  1358. case REMOVE_BOUNDS_OP:
  1359. Option_Number = REMOVE_BOUNDS;
  1360. break;
  1361. case CYCLIC_ANIMATION_OP:
  1362. Option_Number = CYCLIC_ANIMATION;
  1363. break;
  1364. case PRE_SCENE_CMD_OP:
  1365. strcpy(opts.Shellouts[PRE_SCENE_SHL].Command, value);
  1366. break;
  1367. case PRE_FRAME_CMD_OP:
  1368. strcpy(opts.Shellouts[PRE_FRAME_SHL].Command, value);
  1369. break;
  1370. case POST_FRAME_CMD_OP:
  1371. strcpy(opts.Shellouts[POST_FRAME_SHL].Command, value);
  1372. break;
  1373. case POST_SCENE_CMD_OP:
  1374. strcpy(opts.Shellouts[POST_SCENE_SHL].Command, value);
  1375. break;
  1376. case USER_ABORT_CMD_OP:
  1377. strcpy(opts.Shellouts[USER_ABORT_SHL].Command, value);
  1378. break;
  1379. case FATAL_ERROR_CMD_OP:
  1380. strcpy(opts.Shellouts[FATAL_SHL].Command, value);
  1381. break;
  1382. case PRE_SCENE_RET_OP:
  1383. Do_Return_Option(PRE_SCENE_SHL, value);
  1384. break;
  1385. case PRE_FRAME_RET_OP:
  1386. Do_Return_Option(PRE_FRAME_SHL, value);
  1387. break;
  1388. case POST_FRAME_RET_OP:
  1389. Do_Return_Option(POST_FRAME_SHL, value);
  1390. break;
  1391. case POST_SCENE_RET_OP:
  1392. Do_Return_Option(POST_SCENE_SHL, value);
  1393. break;
  1394. case USER_ABORT_RET_OP:
  1395. Do_Return_Option(USER_ABORT_SHL, value);
  1396. break;
  1397. case FATAL_ERROR_RET_OP:
  1398. Do_Return_Option(FATAL_SHL, value);
  1399. break;
  1400. case OUTPUT_ALPHA_OP:
  1401. Option_Number = OUTPUT_ALPHA;
  1402. break;
  1403. case FIELD_RENDER_OP:
  1404. opts.FrameSeq.Field_Render_Flag = istrue(value);
  1405. return;
  1406. case ODD_FIELD_OP:
  1407. opts.FrameSeq.Odd_Field_Flag = istrue(value);
  1408. return;
  1409. case SAMPLING_METHOD_OP:
  1410. opts.Tracing_Method = atoi(value);
  1411. return;
  1412. case BITS_PER_COLOR_OP:
  1413. case BITS_PER_COLOUR_OP:
  1414. opts.OutputQuality = atoi(value);
  1415. opts.OutputQuality = max(5, opts.OutputQuality);
  1416. opts.OutputQuality = min(16, opts.OutputQuality);
  1417. return;
  1418. case DISPLAY_GAMMA_OP:
  1419. if (sscanf (value, DBL_FORMAT_STRING, &floatval) != SCANF_EOF)
  1420. {
  1421. if (floatval > 0.0)
  1422. opts.DisplayGamma = floatval;
  1423. }
  1424. return;
  1425. case INCLUDE_INI_OP:
  1426. if (!parse_ini_file(value))
  1427. {
  1428. Error ("Could not open Include_Ini='%s'.\n", value);
  1429. }
  1430. return;
  1431. default:
  1432. Warning(0.0,"Unimplemented INI '%s'.\n",Option_Variable[variable].Token_Name);
  1433. return;
  1434. }
  1435. if (Option_Number != 0)
  1436. {
  1437. if (istrue(value))
  1438. {
  1439. opts.Options |= Option_Number;
  1440. }
  1441. else
  1442. {
  1443. opts.Options &= ~Option_Number;
  1444. }
  1445. }
  1446. }
  1447. /*****************************************************************************
  1448. *
  1449. * FUNCTION
  1450. *
  1451. * istrue
  1452. *
  1453. * INPUT
  1454. *
  1455. * OUTPUT
  1456. *
  1457. * RETURNS
  1458. *
  1459. * AUTHOR
  1460. *
  1461. * POV-Ray Team
  1462. *
  1463. * DESCRIPTION
  1464. *
  1465. * -
  1466. *
  1467. * CHANGES
  1468. *
  1469. * -
  1470. *
  1471. ******************************************************************************/
  1472. static int matches(char *v1,char *v2)
  1473. {
  1474. int i=0;
  1475. int ans=TRUE;
  1476. while ((ans) && (v1[i] != '\0') && (v2[i] != '\0'))
  1477. {
  1478. ans = ans && (v1[i] == tolower(v2[i]));
  1479. i++;
  1480. }
  1481. return(ans);
  1482. }
  1483. static int istrue(char *value)
  1484. {
  1485. return (matches("on",value) || matches("true",value) ||
  1486. matches("yes",value) || matches("1",value));
  1487. }
  1488. static int isfalse(char *value)
  1489. {
  1490. return (matches("off",value) || matches("false",value) ||
  1491. matches("no",value) || matches("0",value));
  1492. }
  1493. /*****************************************************************************
  1494. *
  1495. * FUNCTION
  1496. *
  1497. * Write_INI_File
  1498. *
  1499. * INPUT
  1500. *
  1501. * OUTPUT
  1502. *
  1503. * RETURNS
  1504. *
  1505. * AUTHOR
  1506. *
  1507. * SCD, 2/95
  1508. *
  1509. * DESCRIPTION
  1510. *
  1511. * Writes all options to an INI file with the current input filename's name
  1512. * (by default), or using a specified filename.
  1513. *
  1514. * CHANGES
  1515. *
  1516. * -
  1517. *
  1518. ******************************************************************************/
  1519. void Write_INI_File()
  1520. {
  1521. int op, i;
  1522. char ini_name[FILE_NAME_LENGTH];
  1523. FILE *ini_file;
  1524. if (opts.Ini_Output_File_Name[0]=='\0')
  1525. {
  1526. return;
  1527. }
  1528. if (isfalse(opts.Ini_Output_File_Name))
  1529. {
  1530. return;
  1531. }
  1532. Status_Info("\nWriting INI file...");
  1533. if (istrue(opts.Ini_Output_File_Name))
  1534. {
  1535. strcpy(ini_name,opts.Scene_Name);
  1536. strcat(ini_name,".ini");
  1537. }
  1538. else
  1539. {
  1540. strcpy(ini_name,opts.Ini_Output_File_Name);
  1541. }
  1542. if ((ini_file = fopen(ini_name, WRITE_TXTFILE_STRING)) == NULL)
  1543. {
  1544. Warning (0.0,"Error opening .INI output file '%s' - no file written.\n",
  1545. ini_name);
  1546. return;
  1547. }
  1548. for (op = 0; op < MAX_OPTION; op++)
  1549. {
  1550. if (op == LIBRARY_PATH_OP)
  1551. {
  1552. for (i = 0; i < opts.Library_Path_Index; i++)
  1553. {
  1554. fprintf(ini_file,"%s=%s%s",Option_Variable[op].Token_Name,
  1555. get_ini_value(op, i),NEW_LINE_STRING);
  1556. }
  1557. }
  1558. /* So that we don't get both Bits_Per_Color and Bits_Per_Colour in
  1559. * the INI file. */
  1560. else if ((op != BITS_PER_COLOUR_OP) && (op != INCLUDE_INI_OP))
  1561. {
  1562. fprintf(ini_file,"%s=%s%s",Option_Variable[op].Token_Name,
  1563. get_ini_value(op, 0),NEW_LINE_STRING);
  1564. }
  1565. }
  1566. fclose(ini_file);
  1567. }
  1568. /*****************************************************************************
  1569. *
  1570. * FUNCTION
  1571. *
  1572. * parse_ini_file
  1573. *
  1574. * INPUT
  1575. *
  1576. * OUTPUT
  1577. *
  1578. * RETURNS
  1579. *
  1580. * AUTHOR
  1581. *
  1582. * POV-Ray Team
  1583. *
  1584. * DESCRIPTION
  1585. *
  1586. * Given a file name, open it, parse options from it, close it.
  1587. * Return 1 if file found, 0 if not found.
  1588. *
  1589. * CHANGES
  1590. *
  1591. * -
  1592. *
  1593. ******************************************************************************/
  1594. int parse_ini_file(char *File_Name)
  1595. {
  1596. char Option_Line[512];
  1597. char INI_Name[FILE_NAME_LENGTH];
  1598. char Desired_Section[FILE_NAME_LENGTH];
  1599. char Current_Section[FILE_NAME_LENGTH];
  1600. char *source, *dest;
  1601. FILE *ini_file;
  1602. int Matched, Never_Matched;
  1603. Stage=STAGE_INI_FILE;
  1604. /* File_Name can be of the for "FILE.INI[Section]" where everything
  1605. * before the '[' is the actual name and "[Section]" is the title of
  1606. * a section within that file that starts with the [Section] heading.
  1607. * Only the specified section of the INI file is processed. If no
  1608. * section is specified then only parts of the file without a section
  1609. * header are processed.
  1610. */
  1611. /* Copy the file name part */
  1612. source=File_Name;
  1613. dest=INI_Name;
  1614. while ((*source != '\0') && (*source != '['))
  1615. {
  1616. *(dest++) = *(source++);
  1617. }
  1618. *dest = '\0';
  1619. /* Copy the section name part */
  1620. dest = Desired_Section;
  1621. while ((*source != '\0') && (*source != ']'))
  1622. {
  1623. *(dest++) = *(source++);
  1624. }
  1625. *dest = *source;
  1626. *(++dest)='\0';
  1627. if ((ini_file = Locate_File(INI_Name, READ_TXTFILE_STRING,".ini",".INI",NULL,FALSE)) == NULL)
  1628. {
  1629. return(FALSE);
  1630. }
  1631. *Current_Section='\0';
  1632. Matched = (*Desired_Section == '\0');
  1633. Never_Matched=TRUE;
  1634. while (fgets(Option_Line, 512, ini_file) != NULL)
  1635. {
  1636. if (*Option_Line == '[')
  1637. {
  1638. source=Option_Line;
  1639. dest=Current_Section;
  1640. while ((*source != '\0') && (*source != ']'))
  1641. {
  1642. *(dest++) = *(source++);
  1643. }
  1644. *dest = *source;
  1645. *(++dest)='\0';
  1646. Matched = (pov_stricmp(Current_Section, Desired_Section) == 0);
  1647. }
  1648. else
  1649. {
  1650. if (Matched)
  1651. {
  1652. parse_option_line(Option_Line);
  1653. Never_Matched=FALSE;
  1654. }
  1655. }
  1656. }
  1657. if (Never_Matched)
  1658. {
  1659. Warning(0.0,"Never found section %s in file %s.\n",Desired_Section,INI_Name);
  1660. }
  1661. fclose(ini_file);
  1662. return(TRUE);
  1663. }
  1664. /*****************************************************************************
  1665. *
  1666. * FUNCTION
  1667. *
  1668. * parse_option_line
  1669. *
  1670. * INPUT
  1671. *
  1672. * OUTPUT
  1673. *
  1674. * RETURNS
  1675. *
  1676. * AUTHOR
  1677. *
  1678. * POV-Ray Team
  1679. *
  1680. * DESCRIPTION
  1681. *
  1682. * Given a string containing a line of text, split it into individual
  1683. * switches or options and then pass them off to be parsed by parse_switch
  1684. * or process_variable. This routine is called by parse_ini_file,
  1685. * by the main with argv[] and by READ_ENV_VAR_????
  1686. *
  1687. * CHANGES
  1688. *
  1689. * Mar 1996 : Allow ';' in an option, if it is escaped [AED]
  1690. *
  1691. ******************************************************************************/
  1692. void parse_option_line(char *Option_Line)
  1693. {
  1694. char *source, *dest;
  1695. char Option_String[512];
  1696. int i,Found;
  1697. source = Option_Line;
  1698. while (TRUE)
  1699. {
  1700. /* skip leading white space */
  1701. while (((int)*source > 0) && ((int)*source < 33))
  1702. {
  1703. source++;
  1704. }
  1705. /* Quit when finished or ignore if commented */
  1706. if ((*source == '\0') || (*source == ';'))
  1707. {
  1708. return;
  1709. }
  1710. if ((*source == '=') || (*source == '#'))
  1711. {
  1712. Error("'=' or '#' must be preceded by a keyword.");
  1713. }
  1714. /* Copy everything that is not a space, an equals or a comment
  1715. into Option_String
  1716. */
  1717. dest = Option_String;
  1718. while ((isprint((int)*source)) &&
  1719. (*source != ' ') &&
  1720. (*source != '=') &&
  1721. (*source != '#') &&
  1722. (*source != ';'))
  1723. {
  1724. *(dest++) = *(source++);
  1725. }
  1726. *dest = '\0';
  1727. /* At this point, nearly all options that start with a "-" are
  1728. * options. However the syntax for the +I and the +O
  1729. * command-line switches, allows a space to appear between the
  1730. * switch and the name. For example: "+I MYFILE.POV" is legal.
  1731. * Since "-" is a legal input and output filename for stdin or
  1732. * stdout we must parse this before we try to read other options.
  1733. * If we encounter a "-" without a following option immediately
  1734. * after a +I or +O switch, it must mean that. The flags
  1735. * inflag and outflag indicate that there was a +I or +O switch
  1736. * parsed just before this file name.
  1737. */
  1738. if (inflag)
  1739. {
  1740. inflag = FALSE;
  1741. if (pov_stricmp(Option_String, "-") == 0 ||
  1742. pov_stricmp(Option_String, "stdin") == 0)
  1743. {
  1744. strcpy (opts.Input_File_Name, "stdin");
  1745. opts.Options |= FROM_STDIN;
  1746. continue;
  1747. }
  1748. else if ((*Option_String != '+') && (*Option_String != '-'))
  1749. {
  1750. strncpy (opts.Input_File_Name, Option_String, FILE_NAME_LENGTH);
  1751. continue;
  1752. }
  1753. }
  1754. if (outflag)
  1755. {
  1756. outflag = FALSE;
  1757. if (pov_stricmp(Option_String, "-") == 0 ||
  1758. pov_stricmp(Option_String, "stdout") == 0)
  1759. {
  1760. strcpy (opts.Output_File_Name, "stdout");
  1761. opts.Options |= TO_STDOUT;
  1762. continue;
  1763. }
  1764. else if ((*Option_String != '+') && (*Option_String != '-'))
  1765. {
  1766. strncpy (opts.Output_File_Name, Option_String, FILE_NAME_LENGTH);
  1767. continue;
  1768. }
  1769. }
  1770. /* If its a +/- style switch then just do it */
  1771. if ((*Option_String == '+') || (*Option_String == '-'))
  1772. {
  1773. parse_switch(Option_String);
  1774. continue;
  1775. }
  1776. /* Now search the Option_Variables to see if we find a match */
  1777. Found=-1;
  1778. for (i = 0 ; i < MAX_OPTION; i++)
  1779. {
  1780. if (pov_stricmp(Option_Variable[i].Token_Name, Option_String) == 0)
  1781. {
  1782. Found=Option_Variable[i].Token_Number;
  1783. break;
  1784. }
  1785. }
  1786. if (Found < 0)
  1787. {
  1788. /* When an option string does not begin with a '+' or '-', and
  1789. * is not in the list of valid keywords, then it is assumed to
  1790. * be a file name. Any file names that appear at this point are
  1791. * .INI/.DEF files to be parsed, or it is an error.
  1792. */
  1793. if (++Number_Of_Files > MAX_NESTED_INI)
  1794. {
  1795. Error ("Bad option syntax or too many nested .INI/.DEF files.");
  1796. }
  1797. if (!parse_ini_file(Option_String))
  1798. {
  1799. Error ("Bad option syntax or error opening .INI/.DEF file '%s'.\n", Option_String);
  1800. }
  1801. continue;
  1802. }
  1803. /* If we make it this far, then it must be an .INI-style setting with
  1804. * the keyword already verified in "Found". We now need to verify that
  1805. * an equals sign follows.
  1806. */
  1807. /* skip white space */
  1808. while (((int)*source > 0) && ((int)*source < 33))
  1809. {
  1810. source++;
  1811. }
  1812. if ((*source != '=') && (*source != '#'))
  1813. {
  1814. Error("Missing '=' or '#' after %s in option.",Option_String);
  1815. }
  1816. source++;
  1817. /* Now the entire rest of Option_Line up to but excluding a comment,
  1818. * becomes the variable part of the option.
  1819. */
  1820. /* skip white space */
  1821. while (((int)*source > 0) && ((int)*source < 33))
  1822. {
  1823. source++;
  1824. }
  1825. dest=source;
  1826. /* Cut off comments and any unprintable characters */
  1827. while (*source != '\0')
  1828. {
  1829. /* If the comment character is escaped, pass it through */
  1830. if ((*source == '\\') && (*(source + 1) == ';'))
  1831. {
  1832. *source = ';';
  1833. source++;
  1834. *source = ' ';
  1835. source++;
  1836. }
  1837. else if ((*source == ';') || (! isprint((int)*source) ) )
  1838. {
  1839. *source = '\0';
  1840. }
  1841. else
  1842. {
  1843. source++;
  1844. }
  1845. }
  1846. process_variable(Found, dest);
  1847. return;
  1848. }
  1849. }
  1850. /*****************************************************************************
  1851. *
  1852. * FUNCTION
  1853. *
  1854. * INPUT
  1855. *
  1856. * OUTPUT
  1857. *
  1858. * RETURNS
  1859. *
  1860. * AUTHOR
  1861. *
  1862. * DESCRIPTION
  1863. *
  1864. * CHANGES
  1865. *
  1866. ******************************************************************************/
  1867. void Do_Stream_Option (int i, char *value)
  1868. {
  1869. if (value==NULL)
  1870. {
  1871. return;
  1872. }
  1873. if (*value == '\0')
  1874. {
  1875. return;
  1876. }
  1877. if (Stream_Info[i].name != NULL)
  1878. {
  1879. POV_FREE(Stream_Info[i].name);
  1880. Stream_Info[i].name = NULL;
  1881. }
  1882. if (istrue(value))
  1883. {
  1884. Stream_Info[i].name = (char *)POV_MALLOC(strlen(DefaultFile[i])+1, "stream name");
  1885. strcpy(Stream_Info[i].name, DefaultFile[i]);
  1886. }
  1887. else
  1888. {
  1889. if (isfalse(value))
  1890. {
  1891. return;
  1892. }
  1893. Stream_Info[i].name = (char *)POV_MALLOC(strlen(value)+1, "stream name");
  1894. strcpy(Stream_Info[i].name, value);
  1895. }
  1896. }
  1897. /*****************************************************************************
  1898. *
  1899. * FUNCTION
  1900. *
  1901. * INPUT
  1902. *
  1903. * OUTPUT
  1904. *
  1905. * RETURNS
  1906. *
  1907. * AUTHOR
  1908. *
  1909. * DESCRIPTION
  1910. *
  1911. * CHANGES
  1912. *
  1913. ******************************************************************************/
  1914. void Do_Return_Option (SHELLTYPE Type, char *value)
  1915. {
  1916. char *s;
  1917. SHELLDATA *Shell=&(opts.Shellouts[Type]);
  1918. Shell->Inverse=FALSE;
  1919. Shell->Ret=IGNORE_RET;
  1920. if (value==NULL)
  1921. return;
  1922. if (*value=='\0')
  1923. return;
  1924. if ((*value=='-') || (*value=='!'))
  1925. {
  1926. Shell->Inverse=TRUE;
  1927. value++;
  1928. }
  1929. if (*value=='\0')
  1930. return;
  1931. if ((s=strchr(ret_string,toupper(*value))) == NULL)
  1932. {
  1933. Warning(0.0,"Bad value in shellout return '%c'. Only '%s' are allowed.\n",*value,ret_string);
  1934. Shell->Ret = IGNORE_RET;
  1935. }
  1936. else
  1937. {
  1938. Shell->Ret = (POV_SHELLOUT_CAST)(s-ret_string);
  1939. }
  1940. }