home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 5 / 05.iso / a / a106 / 2.ddi / GENSCRN.PR_ / GENSCRN.bin
Encoding:
Text File  |  1994-04-28  |  272.4 KB  |  8,642 lines

  1. *:*****************************************************************************
  2. *:
  3. *: Procedure file: C:\FOXPROW\GENSCRN.PRG
  4. *:         System: GenScrn
  5. *:         Author: Microsoft Corp.
  6. *:      Copyright (c) 1990 - 1993 Microsoft Corp.
  7. *:  Last modified: 1/4/93 at 19:33:06
  8. *:
  9. *:  Procs & Fncts: ERRORHANDLER
  10. *:               : SETALL
  11. *:               : OPENPROJDBF()
  12. *:               : PREPSCREENS()
  13. *:               : PREPPLATFORM
  14. *:               : BUILD
  15. *:               : CLEANUP
  16. *:               : CLEANSCRN
  17. *:               : BUILDENABLE
  18. *:               : BUILDDISABLE
  19. *:               : PREPPARAMS
  20. *:               : CLEANPARAM()
  21. *:               : CHECKPARAM()
  22. *:               : PREPFILE
  23. *:               : CLOSEFILE
  24. *:               : NEWWINDOWS()
  25. *:               : NEWDBFS()
  26. *:               : NEWREADCLAUSES
  27. *:               : GETPLATFORM()
  28. *:               : PREPWNAMES
  29. *:               : SCREENUSED()
  30. *:               : ILLEGALNAME()
  31. *:               : GETWITHLIST
  32. *:               : REFRESHPREFS
  33. *:               : SUBDEVINFO()
  34. *:               : DISPATCHBUILD
  35. *:               : BUILDCTRL
  36. *:               : GENSETENVIRON
  37. *:               : GENCLNENVIRON
  38. *:               : GENCLEANUP
  39. *:               : GENPROCEDURES
  40. *:               : PROCSMATCH()
  41. *:               : ISGENPLAT()
  42. *:               : PUTPROCHEAD
  43. *:               : EXTRACTPROCS
  44. *:               : EMITPROC
  45. *:               : EMITBRACKET
  46. *:               : PUTPROC
  47. *:               : GETPROCNUM()
  48. *:               : HASCONFLICT()
  49. *:               : GETFIRSTPROC()
  50. *:               : SCANPROC
  51. *:               : UPDPROCARRAY
  52. *:               : ADDPROCNAME
  53. *:               : GETPLATNUM()
  54. *:               : GENPARAMETER
  55. *:               : GENSECT1
  56. *:               : GENSECT2
  57. *:               : COUNTDIRECTIVES()
  58. *:               : NOTEDIRECTIVES
  59. *:               : FINDSECTION()
  60. *:               : WRITECODE
  61. *:               : WRITELINE
  62. *:               : GENINSERTCODE
  63. *:               : ISPARAMETER()
  64. *:               : ATWNAME()
  65. *:               : ISCOMMENT()
  66. *:               : GENCLAUSECODE
  67. *:               : VALICLAUSE
  68. *:               : GENVALIDBODY
  69. *:               : WHENCLAUSE
  70. *:               : GENWHENBODY
  71. *:               : ACTICLAUSE
  72. *:               : DEATCLAUSE
  73. *:               : SHOWCLAUSE
  74. *:               : PLACESAYS
  75. *:               : GENCLOSEDBFS
  76. *:               : GENOPENDBFS
  77. *:               : UNIQUEDBF()
  78. *:               : GENUSESTMTS
  79. *:               : FINDRELPATH()
  80. *:               : GENORDER
  81. *:               : GENINDEXES()
  82. *:               : GENRELATIONS
  83. *:               : GENRELSTMTS
  84. *:               : BUILDFMT
  85. *:               : ANYWINDOWS
  86. *:               : GENACTISTMTS
  87. *:               : PLACEREAD
  88. *:               : ANYMODAL
  89. *:               : ANYLOCK
  90. *:               : GENWITHCLAUSE
  91. *:               : DOPLACECLAUSE
  92. *:               : FINDREADCLAUSES
  93. *:               : SETCLAUSEFLAGS
  94. *:               : ORCLAUSEFLAGS
  95. *:               : GENREADCLAUSES
  96. *:               : GENCLAUSE
  97. *:               : GENGIVENREAD
  98. *:               : GENDIRECTIVE
  99. *:               : SKIPWHITESPACE()
  100. *:               : DEFPOPUPS
  101. *:               : GENPOPDEFI
  102. *:               : RELPOPUPS
  103. *:               : DEFWINDOWS
  104. *:               : GENDESKTOP
  105. *:               : GENWINDEFI
  106. *:               : GETARRANGE
  107. *:               : GENBOXES
  108. *:               : GENLINES
  109. *:               : GENTEXT
  110. *:               : GENFIELDS
  111. *:               : GENINVBUT
  112. *:               : GENTXTRGN
  113. *:               : GENPUSH
  114. *:               : GENRADBUT
  115. *:               : GENCHKBOX
  116. *:               : GENLIST
  117. *:               : GENPICTURE
  118. *:               : GENSPINNER
  119. *:               : FROMPOPUP
  120. *:               : GENPOPUP
  121. *:               : ELEMRANGE
  122. *:               : GENACTWINDOW
  123. *:               : GENDEFAULT
  124. *:               : ANYBITMAPCTRL
  125. *:               : CHOPPICTURE
  126. *:               : ANYDISABLED
  127. *:               : ANYPICTURE
  128. *:               : ANYSCROLL
  129. *:               : ANYTAB
  130. *:               : ANYFONT
  131. *:               : ANYSTYLE
  132. *:               : ANYPATTERN
  133. *:               : ANYSCHEME
  134. *:               : ANYPEN
  135. *:               : ANYVALID
  136. *:               : ANYTITLEORFOOTER
  137. *:               : ANYWHEN
  138. *:               : ANYMESSAGE
  139. *:               : ANYERROR
  140. *:               : ANYFILL
  141. *:               : ANYWINDOWCHARS
  142. *:               : ANYBORDER
  143. *:               : ANYWALLPAPER
  144. *:               : ANYICON
  145. *:               : WINDOWFROMTO
  146. *:               : HEADER
  147. *:               : GENFUNCHEADER
  148. *:               : COMMENTBLOCK
  149. *:               : PROCCOMMENTBLOCK
  150. *:               : GENCOMMENT
  151. *:               : BASENAME()
  152. *:               : STRIPEXT()
  153. *:               : STRIPPATH()
  154. *:               : STRIPCR()
  155. *:               : ADDBS()
  156. *:               : JUSTFNAME()
  157. *:               : JUSTPATH()
  158. *:               : FORCEEXT()
  159. *:               : WHATSTYLE()
  160. *:               : UNIQUEWIN()
  161. *:               : ADDTOCTRL
  162. *:               : OKTOGENERATE()
  163. *:               : OBJECT()
  164. *:               : COMBINE
  165. *:               : ACTTHERM
  166. *:               : UPDTHERM
  167. *:               : DEACTTHERMO
  168. *:               : ESCHANDLER
  169. *:               : ERRLOG
  170. *:               : ERRSHOW
  171. *:               : OPENERRFILE
  172. *:               : PUSHINDENT
  173. *:               : POPINDENT
  174. *:               : COUNTPLATFORMS
  175. *:               : LOOKUPPLATFORM
  176. *:               : GETPARAM()
  177. *:               : MATCH()
  178. *:               : WORDNUM()
  179. *:               : GETCNAME()
  180. *:               : NOTEAREA
  181. *:               : CLEARAREAS
  182. *:               : PUTMSG
  183. *:               : VERSIONCAP()
  184. *:               : MULTIPLAT()
  185. *:               : SEEKHEADER
  186. *:               : GETPLATNAME()
  187. *:               : INSERTFILE
  188. *:
  189. *:          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  190. *:               : SETALL             (procedure in GENSCRN.PRG)
  191. *:               : OPENPROJDBF()      (function  in GENSCRN.PRG)
  192. *:               : PREPSCREENS()      (function  in GENSCRN.PRG)
  193. *:               : PREPPLATFORM       (procedure in GENSCRN.PRG)
  194. *:               : BUILD              (procedure in GENSCRN.PRG)
  195. *:               : CLEANUP            (procedure in GENSCRN.PRG)
  196. *:
  197. *:      Documented              FoxDoc version 3.00a
  198. *:*****************************************************************************
  199. *
  200. * GENSCRN - Screen Code Generator.
  201. *
  202. * Copyright (c) 1990 - 1993 Microsoft Corp.
  203. * One Microsoft Way
  204. * Redmond, WA 98502
  205. *
  206. * Description:
  207. * This program generates code for objects designed and built with
  208. * FoxPro screen builder.
  209. *
  210. * Notes:
  211. * In this program, for clarity/readability reasons, we use variable
  212. * names that are longer than 10 characters.  Note, however, that only
  213. * the first 10 characters are significant.
  214. *
  215. PARAMETER m.projdbf, m.recno
  216. PRIVATE ALL
  217.  
  218. IF SET("TALK") = "ON"
  219.    SET TALK OFF
  220.    m.talkset = "ON"
  221. ELSE
  222.    m.talkset = "OFF"
  223. ENDIF
  224.  
  225. m.escape = SET("ESCAPE")
  226. ON ESCAPE
  227. SET ESCAPE OFF
  228. m.trbetween = SET("TRBET")
  229. SET TRBET OFF
  230. m.comp = SET("COMPATIBLE")
  231. SET COMPATIBLE FOXPLUS
  232. mdevice = SET("DEVICE")
  233. SET DEVICE TO SCREEN
  234.  
  235. *
  236. * Declare Global Constants
  237. *
  238. #DEFINE c_otscreen         1
  239. #DEFINE c_otworkarea       2
  240. #DEFINE c_otindex          3
  241. #DEFINE c_otrel                    4
  242. #DEFINE c_ottext           5
  243. #DEFINE c_otline           6
  244. #DEFINE c_otbox            7
  245. #DEFINE c_otlist          11
  246. #DEFINE c_ottxtbut        12
  247. #DEFINE c_otradbut        13
  248. #DEFINE c_otchkbox        14
  249. #DEFINE c_otfield         15
  250. #DEFINE c_otpopup         16
  251. #DEFINE c_otpicture       17
  252. #DEFINE c_otinvbut        20
  253. #DEFINE c_otspinner       22
  254.  
  255. #DEFINE c_authorlen       45
  256. #DEFINE c_complen         45
  257. #DEFINE c_addrlen         45
  258. #DEFINE c_citylen         20
  259. #DEFINE c_statlen          5
  260. #DEFINE c_ziplen          10
  261. #DEFINE c_countrylen      40
  262.  
  263. #DEFINE c_sgsay            0
  264. #DEFINE c_sgget            1
  265. #DEFINE c_sgedit           2
  266. #DEFINE c_sgfrom           3
  267. #DEFINE c_sgbox            4
  268. #DEFINE c_sgboxd           5
  269. #DEFINE c_sgboxp           6
  270. #DEFINE c_sgboxc           7
  271.  
  272. * Determines whether SHOW snippets are checked for suspicious SHOW GETS statements
  273. #DEFINE c_checkshow        1
  274.  
  275. #DEFINE c_maxwinds        25
  276. #DEFINE c_maxpops         25
  277. #DEFINE c_maxscreens       5
  278. #DEFINE c_maxplatforms     4
  279. #DEFINE c_20scxflds               57
  280. #DEFINE c_scxflds         79
  281. #DEFINE c_pjxflds         31
  282. #DEFINE c_pjx20flds       33
  283.  
  284. #DEFINE c_esc                   CHR(27)
  285. #DEFINE c_null                  CHR(0)
  286. #DEFINE c_cret                  CHR(13)
  287. #DEFINE c_under                 "_"
  288.  
  289. ***** CGC MMM *****     1994.2.28
  290. *#DEFINE c_single                "┌─┐│┘─└│"
  291. #DEFINE c_single                "\x01\x08\x02\x06\x05\x08\x03\x06"
  292.  
  293. #DEFINE c_double                "╔═╗║╝═╚║"
  294. #DEFINE c_panel                 "████████"
  295. #DEFINE c_fromone               1
  296. #DEFINE c_untilend              0
  297.  
  298. #DEFINE c_error_1               "Minor"
  299. #DEFINE c_error_2               "Serious"
  300. #DEFINE c_error_3               "Fatal"
  301.  
  302. #DEFINE c_dlgface               "MS Sans Serif"
  303. #DEFINE c_dlgsize               8.000
  304. #DEFINE c_dlgstyle              "B"
  305.  
  306. #DEFINE c_genexpr    0
  307. #DEFINE c_gencode    1
  308. #DEFINE c_genboth    -1
  309. m.g_genparams = PARAMETERS()
  310. * DO inittick
  311. *
  312. * Declare Variables
  313. *
  314. STORE "" TO m.cursor, m.consol, m.bell, m.exact, ;
  315.    m.safety, m.fixed, m.print, m.delimiters, m.unique, mudfparms, ;
  316.    m.fields, mfieldsto, m.mdecpoint, m.origpretext, m.mcollate
  317. STORE 0 TO m.deci, m.memowidth
  318.  
  319. m.g_closefiles = .F.           && Generate code to close files?
  320. m.g_current    = ""            && current DBF
  321. m.g_defasch1   = 0                     && Default color scheme 1
  322. m.g_defasch2   = 0                     && Default color scheme 2
  323. m.g_defwin     = .F.           && Generate code to define windows?
  324. m.g_errlog     = ""                    && Path + name of .ERR file
  325. m.g_homedir    = ""                    && Application Home Directory
  326. m.g_idxfile    = 'idxfile.idx' && Index file
  327. m.g_itse       = c_null        && Designating character from #ITSEXPRESSION
  328. m.g_lastwindow = ""            && Name of last window defined
  329. m.g_keyno      = 0
  330. m.g_havehand = .F.
  331. m.g_redefi     = .F.           && Don't redefine windows
  332. m.g_screen     = 0             && Screen currently being generated.  Also used in error messages.
  333. m.g_nscreens   = 0             && Number of screens
  334. m.g_nwindows   = 0             && Number of unique windows in this platform
  335. m.g_multreads  = .F.           && Multiple reads?
  336. m.g_openfiles  = .F.           && Generate code to open files?
  337. m.g_orghandle  = -1            && File handle for ctrl file
  338. m.g_outfile    = ""            && Output file name
  339. m.g_projalias  = ""            && Project database alias
  340. m.g_projpath   = ""
  341. m.g_rddir      = .F.           && Is there a #READCLAUSES directive?
  342. m.g_windclauses= ""            && #WCLAUSES parameters for DEFINE WINDOW
  343. m.g_rddirno    = 0             && Number of 1st screen with #READ directive
  344. m.g_readcycle  = .F.           && READ CYCLE?
  345. m.g_readlock   = .F.           && READ LOCK/NOLOCK?
  346. m.g_readmodal  = .F.           && READ MODAL?
  347. m.g_readborder = .F.           && READ BORDER?
  348. m.g_relwin     = .F.           && Generate code to release windows?
  349. m.g_moddesktop = .F.
  350. m.g_snippcnt   = 0             && Count of snippets
  351. m.g_somepops   = .F.           && Any Generated popups?
  352. m.g_status     = 0
  353. m.g_thermwidth = 0             && Thermometer width
  354. m.g_tmpfile    = SYS(3)+".tmp" && Temporary file
  355. m.g_tmphandle  = -1            && File handle for tmp file
  356. m.g_windows    = .F.           && Any windows in screen files?
  357. m.g_withlist   = ""
  358. m.g_workarea   = 0
  359. m.g_genvers        = ""            && version we are generating for
  360. m.g_thisvers   = ""            && version we are running under now
  361. m.g_graphic    = .F.
  362. m.g_isfirstproc= .T.           && is this the first procedure emitted?
  363. m.g_procsmatch = .F.           && are cleanup snippets for all platforms identical
  364. m.g_noread     = .F.           && omit the read statement?
  365. m.g_noreadplain= .F.           && omit the read statement and the SET TALK TO.. statements?
  366.  
  367. ***** CGC MMM *****
  368. *m.g_boxstrg = ['─','─','│','│','┌','┐','└','┘','─','─','│','│','┌','┐','└','┘']
  369. m.g_boxstrg = [ 8,8,'│','│','┌','┐','└','┘',8,8,'│','│','┌','┐','└','┘']
  370.  
  371. m.g_validtype  = ""
  372. m.g_validname  = ""
  373. m.g_whentype   = ""
  374. m.g_whenname   = ""
  375. m.g_actitype   = ""
  376. m.g_actiname   = ""
  377. m.g_deattype   = ""
  378. m.g_deatname   = ""
  379. m.g_showtype   = ""
  380. m.g_showname   = ""
  381. m.g_showexpr   = ""
  382.  
  383. m.g_sect1start = 0
  384. m.g_sect2start = 0
  385.  
  386. m.g_devauthor  = PADR("Author's Name",c_authorlen," ")
  387. m.g_devcompany = PADR("Company Name",c_complen, " ")
  388. m.g_devaddress = PADR("Address",c_addrlen," ")
  389. m.g_devcity    = PADR("City",c_citylen," ")
  390. m.g_devstate   = "  "
  391. m.g_devzip     = PADR("Zip",c_ziplen," ")
  392. m.g_devctry    = PADR("Country",c_countrylen, " ")
  393.  
  394. m.g_allplatforms = .T.            && generate for all platforms in the SCX?
  395. m.g_numplatforms = 1              && number of platforms we are generating for
  396. m.g_parameter    = ""             && the parameter statement for this SPR
  397. m.g_areacount    = 1              && index into g_areas to count workareas we use
  398. m.g_dblampersand = CHR(38) + CHR(38)   && used in some tight loops.  Concatenate just once here.
  399.  
  400. DO CASE
  401. CASE AT("WINDOWS", UPPER(VERSION())) <> 0
  402.    m.g_thisvers = "WINDOWS"
  403.    m.g_graphic  = .T.
  404. CASE AT("MAC", UPPER(VERSION())) <> 0
  405.    m.g_thisvers = "MAC"
  406.    m.g_graphic  = .T.
  407. CASE AT("UNIX", UPPER(VERSION())) <> 0
  408.    m.g_thisvers = "UNIX"
  409.    m.g_graphic  = .F.
  410. CASE AT("FOXPRO", UPPER(VERSION())) <> 0
  411.    m.g_thisvers = "DOS"
  412.    m.g_graphic  = .F.
  413. OTHERWISE
  414.    DO errorhandler WITH "Unknown FoxPro platform",LINENO(),c_error_3
  415. ENDCASE
  416.  
  417. STORE "" TO m.g_corn1, m.g_corn2, m.g_corn3, m.g_corn4, m.g_corn5, ;
  418.    m.g_corn6, m.g_verti2
  419. STORE "*" TO  m.g_horiz, m.g_verti1
  420.  
  421. * This array stores the names of the DBFs in the environment for this platform
  422. DIMENSION g_dbfs[1]
  423. g_dbfs = ""
  424.  
  425. * If you add arrays that are based on C_MAXSCREENS, remember to check PrepScreens().
  426. * You'll probably need to add the array name there so that if the number of screens
  427. * exceeds C_MAXSCREENS, your array gets expanded too.
  428.  
  429. *       generated popup names associated with scollable lists.
  430. *
  431. *       g_popups[*,1] - screen basename
  432. *       g_popups[*,2] - record number
  433. *       g_popups[*,3] - generated popup name
  434. *
  435. DIMENSION g_popups[C_MAXPOPS,3]
  436. g_popups = ""
  437.  
  438. *       screen file name array definition
  439. *
  440. *       g_screens[*,1] - screen fully qualified name
  441. *       g_screens[*,2] - window name if any
  442. *       g_screens[*,3] - recno in proj dbf
  443. *       g_screens[*,4] - initially opened?
  444. *       g_screens[*,5] - alias
  445. *       g_screens[*,6] - 2.0 screen file?
  446. *       g_screens[*,7] - Platform to generate from
  447. *
  448. DIMENSION g_screens[C_MAXSCREENS,7]
  449. g_screens = ""
  450.  
  451. * Array to store window stack.
  452. * g_wndows[*,1]  - Window name
  453. * g_wndows[*,2]  - Window sequence
  454. DIMENSION g_wndows[C_MAXWINDS,2]
  455. g_wndows = ""
  456.  
  457. * Store the substitution string for window names
  458. DIMENSION g_wnames[C_MAXSCREENS, C_MAXPLATFORMS]
  459. g_wnames = ""
  460.  
  461. * g_platforms holds a list of platforms in common among all screens
  462. DIMENSION g_platforms[C_MAXSCREENS]
  463. g_platforms = ""
  464.  
  465. * g_platprocs is a parallel array to g_platforms.  It holds the name
  466. * of the procedure to contain the setup snippet and all the @SAYs
  467. * and @GETs for the corresponding platform.
  468. DIMENSION g_platproc[C_MAXSCREENS]
  469. g_platproc = ""
  470.  
  471. * g_areas holds a list of areas we opened files in during this gen and that
  472. * we need to close on exit.
  473. DIMENSION g_areas[256]
  474. g_areas = 0
  475.  
  476. * g_firstproc holds the line number of the first PROCEDURE or FUNCTION in
  477. * the cleanup snippet of each screen.
  478. DIMENSION g_firstproc[C_MAXSCREENS]
  479. g_firstproc = 0
  480.  
  481. DIMENSION g_platlist[C_MAXPLATFORMS]
  482. g_platlist[1] = "DOS"
  483. g_platlist[2] = "WINDOWS"
  484. g_platlist[3] = "MAC"
  485. g_platlist[4] = "UNIX"
  486.  
  487. DIMENSION g_procs[1,C_MAXPLATFORMS+3]
  488. * First column is a procedure name
  489. * Second through n-th column is the line number in the cleanup snippet where
  490. *    a procedure with this name starts.
  491. * C_MAXPLATFORMS+2 column is a 1 if this procedure has been emitted.
  492. * C_MAXPLATFORMS+3 column holds the parameter statement, if any.
  493. * One row for each unique procedure name found in the cleanup snippet for any platform.
  494. g_procs = -1
  495. g_procs[1,1] = ""
  496. g_procs[1,C_MAXPLATFORMS+3] = ""
  497. g_procnames = 0   && the number we've found so far
  498.  
  499. ** formfeed
  500. **
  501. ** Main program
  502. **
  503.  
  504. m.onerror = ON("ERROR")
  505. ON ERROR DO errorhandler WITH MESSAGE(), LINENO(), c_error_3
  506.  
  507. IF m.g_genparams < 2
  508.    DO errorhandler WITH "Invalid number of parameters passed to"+;
  509.       " the generator",LINENO(),c_error_3
  510.    RETURN m.g_status
  511. ENDIF
  512.  
  513. DO setall
  514.  
  515. IF openprojdbf(m.projdbf, m.recno) AND prepscreens(m.g_thisvers) AND prepplatform()
  516.    DO BUILD
  517. ENDIF
  518.  
  519. DO cleanup
  520.  
  521. RETURN m.g_status
  522.  
  523. ** formfeed
  524. **
  525. ** Code Responsible for Genscrn's environment setting.
  526. **
  527.  
  528. *
  529. * SETALL - Create program's environment.
  530. *
  531. * Description:
  532. * Save the user's environment that is being modified by the GENSCRN,
  533. * then issue various SET commands.
  534. *
  535. *!*****************************************************************************
  536. *!
  537. *!      Procedure: SETALL
  538. *!
  539. *!      Called by: GENSCRN.PRG
  540. *!
  541. *!*****************************************************************************
  542. PROCEDURE setall
  543. CLEAR PROGRAM
  544. CLEAR GETS
  545.  
  546. m.g_workarea = SELECT()
  547. m.delimiters = SET('TEXTMERGE',1)
  548. SET TEXTMERGE DELIMITERS TO
  549. mudfparms = SET('UDFPARMS')
  550. SET UDFPARMS TO VALUE
  551.  
  552. m.mfieldsto = SET("FIELDS",1)
  553. m.fields = SET("FIELDS")
  554. m.memowidth = SET("MEMOWIDTH")
  555. SET MEMOWIDTH TO 256
  556. m.cursor = SET("CURSOR")
  557. SET CURSOR OFF
  558. m.consol = SET("CONSOLE")
  559. SET CONSOLE OFF
  560. m.bell = SET("BELL")
  561. SET BELL OFF
  562. m.exact = SET("EXACT")
  563. SET EXACT ON
  564. m.safety = SET("SAFETY")
  565. m.deci = SET("DECIMALS")
  566. SET DECIMALS TO 0
  567. m.mdecpoint = SET("POINT")
  568. SET POINT TO "."
  569. m.fixed = SET("FIXED")
  570. SET FIXED ON
  571. m.print = SET("PRINT")
  572. SET PRINT OFF
  573. m.unique = SET("UNIQUE")
  574. SET UNIQUE OFF
  575. m.mcollate = SET("COLLATE")
  576. SET COLLATE TO "machine"
  577. m.origpretext = _PRETEXT
  578. _PRETEXT = ""
  579.  
  580. *
  581. * CLEANUP - Restore environment to pre-execution state.
  582. *
  583. * Description:
  584. * Put SET command settings back the way we found them.
  585. *
  586. *!*****************************************************************************
  587. *!
  588. *!      Procedure: CLEANUP
  589. *!
  590. *!      Called by: GENSCRN.PRG
  591. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  592. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  593. *!
  594. *!          Calls: CLEANSCRN          (procedure in GENSCRN.PRG)
  595. *!               : CLEARAREAS         (procedure in GENSCRN.PRG)
  596. *!
  597. *!*****************************************************************************
  598. PROCEDURE cleanup
  599. PRIVATE m.i, m.delilen, m.ldelimi, m.rdelimi
  600. IF EMPTY(m.g_projalias)
  601.    RETURN
  602. ENDIF
  603. SELECT (m.g_projalias)
  604. USE
  605. DO cleanscrn
  606. DO clearareas  && clear the workareas we opened during this run
  607. SELECT (m.g_workarea)
  608.  
  609. DELETE FILE (m.g_tmpfile)
  610. DELETE FILE (m.g_idxfile)
  611.  
  612. m.delilen = LEN(m.delimiters)
  613. m.ldelimi = SUBSTR(m.delimiters,1,;
  614.    IIF(MOD(m.delilen,2)=0,m.delilen/2,CEILING(m.delilen/2)))
  615. m.rdelimi = SUBSTR(m.delimiters,;
  616.    IIF(MOD(m.delilen,2)=0,m.delilen/2+1,CEILING(m.delilen/2)+1))
  617. SET TEXTMERGE DELIMITERS TO m.ldelimi, m.rdelimi
  618.  
  619. SET FIELDS TO &mfieldsto
  620. IF m.fields = "ON"
  621.    SET FIELDS ON
  622. ELSE
  623.    SET FIELDS OFF
  624. ENDIF
  625. IF m.cursor = "ON"
  626.    SET CURSOR ON
  627. ELSE
  628.    SET CURSOR OFF
  629. ENDIF
  630. IF m.consol = "ON"
  631.    SET CONSOLE ON
  632. ELSE
  633.    SET CONSOLE OFF
  634. ENDIF
  635. IF m.escape = "ON"
  636.    SET ESCAPE ON
  637. ELSE
  638.    SET ESCAPE OFF
  639. ENDIF
  640. IF m.bell = "ON"
  641.    SET BELL ON
  642. ELSE
  643.    SET BELL OFF
  644. ENDIF
  645. IF m.exact = "ON"
  646.    SET EXACT ON
  647. ELSE
  648.    SET EXACT OFF
  649. ENDIF
  650. IF m.safety = "ON"
  651.    SET SAFETY ON
  652. ELSE
  653.    SET SAFETY OFF
  654. ENDIF
  655. IF m.comp = "ON"
  656.    SET COMPATIBLE ON
  657. ENDIF
  658. IF m.print = "ON"
  659.    SET PRINT ON
  660. ENDIF
  661. SET DECIMALS TO m.deci
  662. SET MEMOWIDTH TO m.memowidth
  663. SET DEVICE TO &mdevice
  664. SET UDFPARMS TO &mudfparms
  665. SET POINT TO "&mdecpoint"
  666. SET COLLATE TO "&mcollate"
  667. IF m.fixed = "OFF"
  668.    SET FIXED OFF
  669. ENDIF
  670. IF m.trbetween = "ON"
  671.    SET TRBET ON
  672. ENDIF
  673. IF m.talkset = "ON"
  674.    SET TALK ON
  675. ENDIF
  676. IF m.unique = "ON"
  677.    SET UNIQUE ON
  678. ENDIF
  679. SET MESSAGE TO
  680. _PRETEXT = m.origpretext
  681. * Leave this array if dbglevel is defined.  Used for profiling.
  682. * IF TYPE("dbglevel") = "U"
  683. *   RELEASE ticktock
  684. * ENDIF
  685.  
  686. ON ERROR &onerror
  687.  
  688. *
  689. * CLEANSCRN - Clean up after each screen set generation, once per platform
  690. *
  691. *!*****************************************************************************
  692. *!
  693. *!      Procedure: CLEANSCRN
  694. *!
  695. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  696. *!
  697. *!*****************************************************************************
  698. PROCEDURE cleanscrn
  699. PRIVATE m.i
  700. FOR m.i = 1 TO m.g_nscreens
  701.    m.g_screen = i
  702.    IF NOT EMPTY(g_screens[m.i,4])
  703.       LOOP
  704.    ENDIF
  705.    IF USED(g_screens[m.i,5])
  706.       SELECT (g_screens[m.i,5])
  707.       USE
  708.    ENDIF
  709. ENDFOR
  710. m.g_screen = 0
  711.  
  712.  
  713. ** formfeed
  714. **
  715. ** Environment setting code in preparation for generation.
  716. **
  717.  
  718. *
  719. * BUILDENABLE - Enable code generation.
  720. *
  721. * Description:
  722. * Call prepfile to open output file(s).
  723. * If error(s) encountered in prepfile then exit, otherwise
  724. * SET TEXTMERGE ON
  725. *
  726. * Returns: .T. on success; .F. on failure
  727. *
  728. *!*****************************************************************************
  729. *!
  730. *!      Procedure: BUILDENABLE
  731. *!
  732. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  733. *!
  734. *!          Calls: PREPFILE           (procedure in GENSCRN.PRG)
  735. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  736. *!
  737. *!*****************************************************************************
  738. PROCEDURE buildenable
  739. DO prepfile WITH m.g_outfile, m.g_orghandle
  740. DO prepfile WITH m.g_tmpfile, m.g_tmphandle
  741.  
  742. SET TEXTMERGE ON
  743. ON ESCAPE DO eschandler
  744. SET ESCAPE ON
  745.  
  746. *
  747. * BUILDDISABLE - Disable code generation.
  748. *
  749. * Description:
  750. * Issue the command SET TEXTMERGE OFF.
  751. * Close the generated output file.
  752. * Close the temporary file.
  753. * If anything goes wrong display appropriate message to the user.
  754. *
  755. *!*****************************************************************************
  756. *!
  757. *!      Procedure: BUILDDISABLE
  758. *!
  759. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  760. *!               : ESCHANDLER         (procedure in GENSCRN.PRG)
  761. *!
  762. *!          Calls: CLOSEFILE          (procedure in GENSCRN.PRG)
  763. *!
  764. *!*****************************************************************************
  765. PROCEDURE builddisable
  766. SET ESCAPE OFF
  767. ON ESCAPE
  768. SET TEXTMERGE OFF
  769. IF m.g_havehand
  770.    DO closefile WITH m.g_orghandle
  771.    DO closefile WITH m.g_tmphandle
  772. ENDIF
  773.  
  774. *
  775. * PREPPARAMS - Read through each of the platforms on screen 1
  776. *              and ensure that any parameter statements in #SECTION 1
  777. *              are identical.
  778. *
  779. *!*****************************************************************************
  780. *!
  781. *!      Procedure: PREPPARAMS
  782. *!
  783. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  784. *!
  785. *!          Calls: CHECKPARAM()       (function  in GENSCRN.PRG)
  786. *!
  787. *!*****************************************************************************
  788. PROCEDURE prepparams
  789. PRIVATE m.i, m.j, m.dbalias, m.thisparam
  790. m.g_screen = 1
  791. m.dbalias = g_screens[m.g_screen,5]
  792. SELECT (m.dbalias)
  793. DO CASE
  794. CASE g_screens[m.g_screen,6] OR !multiplat()
  795.    * DOS 2.0 screen or just one 2.5 platform being generated
  796.    GO TOP
  797.    RETURN checkparam(m.g_screen)
  798.  
  799. OTHERWISE
  800.    FOR m.j = 1 TO c_maxplatforms
  801.       LOCATE FOR ALLTRIM(UPPER(platform)) = g_platlist[m.j] AND objtype = c_otscreen
  802.       DO CASE
  803.       CASE !FOUND() OR EMPTY(setupcode)
  804.          LOOP
  805.       CASE !checkparam(m.g_screen)
  806.          RETURN .F.
  807.       ENDCASE
  808.    ENDFOR
  809. ENDCASE
  810. m.g_screen = 0
  811. RETURN .T.
  812.  
  813. *
  814. * CLEANPARAM - Clean up a parameter string so that it may be compared with another one.
  815. *              This function replaces tabs with spaces, capitalizes the string, merges
  816. *              forces single spacing, and strips out CR/LF characters.
  817. *
  818. *!*****************************************************************************
  819. *!
  820. *!       Function: CLEANPARAM
  821. *!
  822. *!      Called by: CHECKPARAM()       (function  in GENSCRN.PRG)
  823. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  824. *!
  825. *!*****************************************************************************
  826. FUNCTION cleanparam
  827. PARAMETER m.p, m.cp
  828. m.cp = UPPER(ALLTRIM(CHRTRAN(m.p,";"+CHR(13)+CHR(10),"")))   && drop CR/LF and continuation chars
  829. m.cp = CHRTRAN(m.cp,CHR(9),' ')   && tabs to spaces
  830. DO WHILE AT('  ',m.cp) > 0         && reduce multiple spaces to a single space
  831.    m.cp = STRTRAN(m.cp,'  ',' ')
  832. ENDDO
  833. DO WHILE AT(', ',m.cp) > 0         && drop spaces after commas
  834.    m.cp = STRTRAN(m.cp,', ',',')
  835. ENDDO
  836. RETURN m.cp
  837.  
  838. *
  839. * CHECKPARAM - See if this parameter statement matches others we have found. Generate
  840. *               an error message if it doesn't.  g_parameter is empty if we haven't
  841. *               seen any parameter statements yet, or it contains the variables in the
  842. *               parameter statement (but not the PARAMETERS keyword) if we have seen one
  843. *               before.
  844. *
  845. *!*****************************************************************************
  846. *!
  847. *!       Function: CHECKPARAM
  848. *!
  849. *!      Called by: PREPPARAMS         (procedure in GENSCRN.PRG)
  850. *!
  851. *!          Calls: GETPARAM()         (function  in GENSCRN.PRG)
  852. *!               : CLEANPARAM()       (function  in GENSCRN.PRG)
  853. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  854. *!
  855. *!*****************************************************************************
  856. FUNCTION checkparam
  857. PARAMETER m.i
  858. PRIVATE m.thisparam
  859. m.thisparam = getparam("setupcode")  && get parameter from setup snippet at current record position
  860.  
  861. IF !EMPTY(m.thisparam)
  862.    IF !EMPTY(m.g_parameter) AND !(cleanparam(m.thisparam) == cleanparam(m.g_parameter))
  863.       DO errorhandler WITH "DOS and Windows setup code has different parameters", ;
  864.          LINENO(), c_error_3
  865.       RETURN .F.
  866.    ELSE
  867.       g_parameter = m.thisparam
  868.    ENDIF
  869. ENDIF
  870. RETURN .T.
  871.  
  872. *
  873. * PREPPLATFORM - Create an array of platform names in the screen set.  Make sure that
  874. *                there is at least one common platform across all SCXs in the screen set.
  875. *                g_platforms comes out of this procedure containing the intersection of
  876. *                the set of platforms in each screen.  If there are no common platforms
  877. *                across all screens, it will be empty.
  878. *
  879. *!*****************************************************************************
  880. *!
  881. *!      Procedure: PREPPLATFORM
  882. *!
  883. *!      Called by: GENSCRN.PRG
  884. *!
  885. *!*****************************************************************************
  886. PROCEDURE prepplatform
  887. PRIVATE m.i, m.j, m.firstscrn, m.p_cur, m.tempplat, m.numtodel, m.in_area, ;
  888.    m.rcount
  889. IF m.g_nscreens <= 0
  890.    RETURN .F.
  891. ENDIF
  892.  
  893. DIMENSION t_platforms[ALEN(g_platforms)]
  894. m.in_area = SELECT()
  895. IF g_screens[1,6]         && First screen is a DOS 2.0 screen
  896.    g_platforms = ""
  897.    g_platforms[1] = "DOS"
  898. ELSE
  899.    IF _DOS
  900.       * Avoid selecting into an array to conserve memory
  901.       SELECT DISTINCT platform FROM (g_screens[1,1]) INTO CURSOR curstemp ;
  902.          ORDER BY platform
  903.       m.rcount = _TALLY
  904.       SELECT curstemp
  905.       DIMENSION g_platforms[m.rcount]
  906.       GOTO TOP
  907.       FOR m.i = 1 TO m.rcount
  908.          g_platforms[m.i] = curstemp->platform
  909.          SKIP
  910.       ENDFOR
  911.       USE                                             && get rid of the cursor
  912.    ELSE
  913.       SELECT DISTINCT platform FROM (g_screens[1,1]) INTO ARRAY g_platforms ;
  914.          ORDER BY platform
  915.    ENDIF
  916. ENDIF
  917.  
  918. m.numtodel = 0   && number of array elements to delete
  919. FOR m.i = 2 TO m.g_nscreens
  920.    m.g_screen = m.i
  921.    IF g_screens[m.i,6]   && DOS 2.0 screen
  922.       DIMENSION t_platforms[1]
  923.       t_platforms = ""
  924.       t_platforms[1] = "DOS"
  925.    ELSE
  926.       IF _DOS
  927.          * Avoid selecting into an array to conserve memory
  928.          SELECT DISTINCT platform FROM (g_screens[m.i,1]) INTO CURSOR curstemp ;
  929.             ORDER BY platform
  930.          m.rcount = _TALLY
  931.          SELECT curstemp
  932.          DIMENSION t_platforms[m.rcount]
  933.          GOTO TOP
  934.          FOR m.k = 1 TO m.rcount
  935.             t_platforms[m.k] = curstemp->platform
  936.             SKIP
  937.          ENDFOR
  938.          USE                                             && get rid of the cursor
  939.       ELSE
  940.          SELECT DISTINCT platform FROM (g_screens[m.i,1]) INTO ARRAY t_platforms ;
  941.             ORDER BY platform
  942.       ENDIF
  943.    ENDIF
  944.  
  945.    * Update g_platforms with the intersection of g_platforms
  946.    *  and t_platforms
  947.    m.j = 1
  948.    DO WHILE m.j < ALEN(g_platforms) -  m.numtodel
  949.       IF !INLIST(TYPE("g_platforms[m.j]"),"L","U") ;
  950.             AND ASCAN(t_platforms,g_platforms[m.j]) = 0
  951.          =ADEL(g_platforms,m.j)
  952.          m.numtodel = m.numtodel + 1
  953.       ELSE
  954.          m.j = m.j + 1
  955.       ENDIF
  956.    ENDDO
  957.  
  958. ENDFOR
  959. SELECT (m.in_area)
  960.  
  961. m.g_screen = 0
  962. * Shrink the unique platform array if necessary
  963. DIMENSION g_platforms[ALEN(g_platforms)-m.numtodel]
  964.  
  965. IF ALEN(g_platforms) <= 0 OR EMPTY(g_platforms[1])
  966.    WAIT WINDOW  "No common platforms in these screens.  Press any key."
  967.    CANCEL
  968. ELSE
  969.    FOR m.j = 1 TO ALEN(g_platforms)
  970.       g_platforms[m.j] = UPPER(ALLTRIM(g_platforms[m.j]))
  971.    ENDFOR
  972.  
  973.    * If the current platform is in the list of common platforms, put it at the top
  974.    m.p_cur = ASCAN(g_platforms, m.g_thisvers)
  975.    IF m.p_cur > 1
  976.       m.tempplat = g_platforms[1]
  977.       g_platforms[1] = g_platforms[m.p_cur]
  978.       g_platforms[m.p_cur] = m.tempplat
  979.    ENDIF
  980. ENDIF
  981. RETURN .T.
  982.  
  983. *
  984. * PREPFILE - Create and open the application output file.
  985. *
  986. * Description:
  987. * Create or open a file that will hold the generated application.
  988. * If error(s) encountered at any time issue an error message
  989. * and return .F.
  990. *
  991. *!*****************************************************************************
  992. *!
  993. *!      Procedure: PREPFILE
  994. *!
  995. *!      Called by: BUILDENABLE        (procedure in GENSCRN.PRG)
  996. *!
  997. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  998. *!
  999. *!*****************************************************************************
  1000. PROCEDURE prepfile
  1001. PARAMETER m.filename, m.ifp
  1002. PRIVATE m.msg
  1003. m.ifp = FCREATE(m.filename)
  1004.  
  1005. IF (m.ifp = -1)
  1006.    m.msg = "Cannot open "+LOWER(m.filename)
  1007.    m.g_havehand = .F.
  1008.    DO errorhandler WITH m.msg, LINENO(), c_error_3
  1009. ELSE
  1010.    m.g_havehand = .T.
  1011. ENDIF
  1012.  
  1013. *
  1014. * CLOSEFILE - Close a low level file opened with FCREATE.
  1015. *
  1016. *!*****************************************************************************
  1017. *!
  1018. *!      Procedure: CLOSEFILE
  1019. *!
  1020. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  1021. *!               : BUILDDISABLE       (procedure in GENSCRN.PRG)
  1022. *!
  1023. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  1024. *!
  1025. *!*****************************************************************************
  1026. PROCEDURE closefile
  1027. PARAMETER m.ifp
  1028. IF (m.ifp > 0) AND !FCLOSE(m.ifp)
  1029.    DO errorhandler WITH "Unable to close the generated file",;
  1030.       LINENO(), c_error_2
  1031. ENDIF
  1032.  
  1033. *
  1034. * PREPSCREENS - Prepare screen file(s) for processing.
  1035. *
  1036. * Description:
  1037. * Called once per platform.
  1038. *
  1039. * Open PJX database, index it to find all screen files belonging
  1040. * to a screen set if part of a project.
  1041. *
  1042. * Open all screen file(s).  If screen file already opened, then
  1043. * select it.  Assign unique aliases to screen with name conflicts.
  1044. * If error is encountered while opening any of the screen files
  1045. * this program will be aborted.
  1046. *
  1047. *!*****************************************************************************
  1048. *!
  1049. *!       Function: PREPSCREENS
  1050. *!
  1051. *!      Called by: GENSCRN.PRG
  1052. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1053. *!
  1054. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  1055. *!               : SCREENUSED()       (function  in GENSCRN.PRG)
  1056. *!               : NOTEAREA           (procedure in GENSCRN.PRG)
  1057. *!               : GETPLATFORM()      (function  in GENSCRN.PRG)
  1058. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  1059. *!               : PREPWNAMES         (procedure in GENSCRN.PRG)
  1060. *!
  1061. *!*****************************************************************************
  1062. FUNCTION prepscreens
  1063. PARAMETER m.gen_version
  1064.  
  1065. PRIVATE m.status, m.projdbf, m.saverec, m.dbname, m.dbalias
  1066. m.status = .T.
  1067.  
  1068. SELECT (m.g_projalias)
  1069. SET SAFETY OFF
  1070. INDEX ON STR(scrnorder) TO (m.g_idxfile) COMPACT
  1071. SET SAFETY ON
  1072. GO TOP
  1073. SCAN FOR NOT DELETED() AND setid = m.g_keyno AND TYPE = 's'
  1074.    m.saverec = RECNO()
  1075.    m.dbname  = FULLPATH(ALLTRIM(name), m.g_projpath)
  1076.    m.g_nscreens = m.g_nscreens + 1
  1077.  
  1078.    IF MOD(m.g_nscreens,5)=0
  1079.       DIMENSION g_screens[ALEN(g_screens,1)+5,7]
  1080.       DIMENSION g_wnames [ALEN(g_wnames)+5,C_MAXPLATFORMS]
  1081.       DIMENSION g_platforms [ALEN(g_platforms)+5]
  1082.       DIMENSION g_firstproc [ALEN(g_firstproc)+5]
  1083.    ENDIF
  1084.  
  1085.    m.dbalias = basename(m.dbname)
  1086.    IF screenused(m.dbalias, m.dbname)
  1087.       g_screens[m.g_nscreens,4] = .T.
  1088.    ELSE
  1089.       g_screens[m.g_nscreens,4] = .F.
  1090.       SELECT 0
  1091.       USE (m.dbname) AGAIN ALIAS (g_screens[m.g_nscreens,5])
  1092.       DO notearea
  1093.    ENDIF
  1094.  
  1095.    DO CASE
  1096.    CASE FCOUNT() = c_scxflds
  1097.       LOCATE FOR platform = m.gen_version
  1098.       IF FOUND()
  1099.          g_screens[m.g_nscreens,6] = .F.
  1100.          g_screens[m.g_nscreens,7] = platform
  1101.       ELSE
  1102.          g_screens[m.g_nscreens,6] = .F.
  1103.          g_screens[m.g_nscreens,7] = getplatform()
  1104.       ENDIF
  1105.    CASE FCOUNT() = c_20scxflds
  1106.       g_screens[m.g_nscreens,6] = .T.
  1107.       g_screens[m.g_nscreens,7] = "DOS"
  1108.    OTHERWISE
  1109.       DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  1110.          c_error_2
  1111.       RETURN .F.
  1112.    ENDCASE
  1113.    g_screens[m.g_nscreens,1] = m.dbname
  1114.  
  1115.    IF NOT EMPTY(STYLE)
  1116.       IF EMPTY(name)
  1117.          g_screens[m.g_nscreens,2] = LOWER(SYS(2015))
  1118.       ELSE
  1119.          g_screens[m.g_nscreens,2] = ALLTRIM(LOWER(name))
  1120.       ENDIF
  1121.       DO prepwnames WITH m.g_nscreens
  1122.    ENDIF
  1123.  
  1124.    SELECT (m.g_projalias)
  1125.    GOTO RECORD m.saverec
  1126.    g_screens[m.g_nscreens,3] = m.saverec
  1127. ENDSCAN
  1128.  
  1129. RETURN m.status
  1130.  
  1131. *!*****************************************************************************
  1132. *!
  1133. *!       Function: NEWWINDOWS
  1134. *!
  1135. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1136. *!
  1137. *!*****************************************************************************
  1138. FUNCTION newwindows
  1139. * Initialize the windows name array and other window-related
  1140. * variables for each platform.
  1141. g_wndows = ""                  && array of window names
  1142. m.g_nwindows = 0               && number of windows
  1143. m.g_lastwindow = ""            && name of last window generated for this platform
  1144. RETURN
  1145.  
  1146. *
  1147. * NEWSCHEMES - Initialize the color schemes for each screen/platform
  1148. *
  1149. *!*****************************************************************************
  1150. *!
  1151. *!       Function: NEWSCHEMES
  1152. *!
  1153. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1154. *!
  1155. *!*****************************************************************************
  1156. FUNCTION newschemes
  1157. m.g_defasch  = 0
  1158. m.g_defasch2 = 0
  1159. RETURN
  1160.  
  1161. *
  1162. * NEWDBFS - Initialize the databases name array for each platform
  1163. *
  1164. *!*****************************************************************************
  1165. *!
  1166. *!       Function: NEWDBFS
  1167. *!
  1168. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1169. *!
  1170. *!*****************************************************************************
  1171. FUNCTION newdbfs
  1172. g_dbfs = ""
  1173. RETURN
  1174.  
  1175. *
  1176. * NEWREADCLAUSES - Initialize the variables that control which READ and WINDOW clauses are
  1177. *                    emitted.
  1178. *
  1179. *!*****************************************************************************
  1180. *!
  1181. *!      Procedure: NEWREADCLAUSES
  1182. *!
  1183. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1184. *!
  1185. *!*****************************************************************************
  1186. PROCEDURE newreadclauses
  1187. m.g_validtype  = ""
  1188. m.g_validname  = ""
  1189. m.g_whentype   = ""
  1190. m.g_whenname   = ""
  1191. m.g_actitype   = ""
  1192. m.g_actiname   = ""
  1193. m.g_deattype   = ""
  1194. m.g_deatname   = ""
  1195. m.g_showtype   = ""
  1196. m.g_showname   = ""
  1197. m.g_showexpr   = ""
  1198.  
  1199. *!*****************************************************************************
  1200. *!
  1201. *!      Procedure: NEWDIRECTIVES
  1202. *!
  1203. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1204. *!
  1205. *!*****************************************************************************
  1206. PROCEDURE newdirectives
  1207. m.g_windclauses= ""            && #WCLAUSES directive
  1208. m.g_rddir      = .F.           && Is there a #READCLAUSES directive?
  1209. m.g_rddirno    = 0             && Number of 1st screen with #READ directive
  1210.  
  1211. *
  1212. * GETPLATFORM - Find which Platform we are supposed to generate for.  If we are trying to
  1213. *               generate for Windows, but there are no windows records in the SCX, use
  1214. *               this function to determine which records to use.
  1215. *
  1216. *!*****************************************************************************
  1217. *!
  1218. *!       Function: GETPLATFORM
  1219. *!
  1220. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1221. *!
  1222. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  1223. *!
  1224. *!*****************************************************************************
  1225. FUNCTION getplatform
  1226.  
  1227. IF m.g_genvers = 'WINDOWS' OR m.g_genvers = 'MAC'
  1228.    LOCATE FOR platform = IIF(m.g_genvers = 'WINDOWS', 'MAC', 'WINDOWS')
  1229.    IF FOUND()
  1230.       RETURN platform
  1231.    ELSE
  1232.       LOCATE FOR platform = 'DOS'
  1233.       IF FOUND()
  1234.          RETURN 'DOS'
  1235.       ELSE
  1236.          LOCATE FOR platform = 'UNIX'
  1237.          IF FOUND()
  1238.             RETURN 'UNIX'
  1239.          ELSE
  1240.             DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  1241.                c_error_2
  1242.          ENDIF
  1243.       ENDIF
  1244.    ENDIF
  1245. ELSE
  1246.    LOCATE FOR platform = IIF(m.g_genvers = 'DOS', 'UNIX', 'DOS')
  1247.    IF FOUND()
  1248.       RETURN platform
  1249.    ELSE
  1250.       LOCATE FOR platform = 'WINDOWS'
  1251.       IF FOUND()
  1252.          RETURN 'DOS'
  1253.       ELSE
  1254.          LOCATE FOR platform = 'MAC'
  1255.          IF FOUND()
  1256.             RETURN 'UNIX'
  1257.          ELSE
  1258.             DO errorhandler WITH "Screen "+m.dbalias+" is invalid",LINENO(),;
  1259.                c_error_2
  1260.          ENDIF
  1261.       ENDIF
  1262.    ENDIF
  1263. ENDIF
  1264. RETURN ""
  1265.  
  1266.  
  1267. *
  1268. * PREPWNAMES - Store #WNAME directive strings.  They must be in the setup snippet.
  1269. *
  1270. *!*****************************************************************************
  1271. *!
  1272. *!      Procedure: PREPWNAMES
  1273. *!
  1274. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1275. *!
  1276. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  1277. *!               : SKIPWHITESPACE()   (function  in GENSCRN.PRG)
  1278. *!
  1279. *!*****************************************************************************
  1280. PROCEDURE prepwnames
  1281. PARAMETER m.scrnno
  1282. PRIVATE m.lineno, m.textline
  1283. m.lineno = ATCLINE('#WNAM',setupcode)
  1284. IF m.lineno > 0
  1285.    m.textline = MLINE(setupcode,m.lineno)
  1286.    IF g_screens[m.scrnno,6])   && DOS 2.0 screen
  1287.       IF ATC('#WNAM',m.textline) = 1
  1288.          g_wnames[m.scrnno, getplatnum("DOS")] = skipwhitespace(m.textline)
  1289.       ENDIF
  1290.    ELSE
  1291.       IF ATC('#WNAM',m.textline) = 1
  1292.          g_wnames[m.scrnno, getplatnum(platform)] = skipwhitespace(m.textline)
  1293.       ENDIF
  1294.    ENDIF
  1295. ENDIF
  1296. RETURN
  1297.  
  1298. *
  1299. * SCREENUSED - Check to see if screen file already opened.
  1300. *
  1301. *!*****************************************************************************
  1302. *!
  1303. *!       Function: SCREENUSED
  1304. *!
  1305. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  1306. *!
  1307. *!          Calls: ILLEGALNAME()      (function  in GENSCRN.PRG)
  1308. *!
  1309. *!*****************************************************************************
  1310. FUNCTION screenused
  1311. PARAMETER m.dbalias, m.fulldbname
  1312. IF NOT USED(m.dbalias)
  1313.    IF illegalname(m.dbalias)
  1314.       g_screens[m.g_nscreens,5] = "S"+SUBSTR(LOWER(SYS(3)),2,8)
  1315.    ELSE
  1316.       g_screens[m.g_nscreens,5] = m.dbalias
  1317.    ENDIF
  1318.    RETURN .F.
  1319. ENDIF
  1320. SELECT (m.dbalias)
  1321. IF RAT(".SCX",DBF())<>0 AND m.fulldbname=DBF()
  1322.    g_screens[m.g_nscreens,5] = m.dbalias
  1323.    RETURN .T.
  1324. ELSE
  1325.    g_screens[m.g_nscreens,5] = "S"+SUBSTR(LOWER(SYS(3)),2,8)
  1326. ENDIF
  1327. RETURN .F.
  1328.  
  1329. *
  1330. * ILLEGALNAME - Check if default alias will be used when this
  1331. *               database is USEd. (i.e., 1st letter is not A-Z,
  1332. *                               a-z or '_', or any one of ramaining letters is not
  1333. *                               alphanumeric.)
  1334. *
  1335. *!*****************************************************************************
  1336. *!
  1337. *!       Function: ILLEGALNAME
  1338. *!
  1339. *!      Called by: SCREENUSED()       (function  in GENSCRN.PRG)
  1340. *!
  1341. *!*****************************************************************************
  1342. FUNCTION illegalname
  1343. PARAMETER m.dname
  1344. PRIVATE m.start, m.aschar, m.length
  1345. m.length = LEN(m.dname)
  1346. m.start  = 0
  1347. IF m.length = 1
  1348.    *
  1349.    * If length 1, then check if default alias can be used,
  1350.    * i.e., name is different than A-J and a-j.
  1351.    *
  1352.    m.aschar = ASC(m.dname)
  1353.    IF (m.aschar >= 65 AND m.aschar <= 74) OR ;
  1354.          (m.aschar >= 97 AND m.aschar <= 106)
  1355.       RETURN .T.
  1356.    ENDIF
  1357. ENDIF
  1358. DO WHILE m.start < m.length
  1359.    m.start  = m.start + 1
  1360.    m.aschar = ASC(SUBSTR(m.dname, m.start, 1))
  1361.    IF m.start<>1 AND (m.aschar >= 48 AND m.aschar <= 57)
  1362.       LOOP
  1363.    ENDIF
  1364.    IF NOT ((m.aschar >= 65 AND m.aschar <= 90) OR ;
  1365.          (m.aschar >= 97 AND m.aschar <= 122) OR m.aschar = 95)
  1366.       RETURN .T.
  1367.    ENDIF
  1368. ENDDO
  1369. RETURN .F.
  1370.  
  1371. *
  1372. * OPENPROJDBF - Prepare Project dbf for processing.
  1373. *
  1374. * Description:
  1375. * Check to see if projdbf has an appropriate number of fields.
  1376. * Find the screen set record.
  1377. * Extract information from the SETID record.
  1378. *
  1379. *!*****************************************************************************
  1380. *!
  1381. *!       Function: OPENPROJDBF
  1382. *!
  1383. *!      Called by: GENSCRN.PRG
  1384. *!
  1385. *!          Calls: NOTEAREA           (procedure in GENSCRN.PRG)
  1386. *!               : STRIPEXT()         (function  in GENSCRN.PRG)
  1387. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  1388. *!               : REFRESHPREFS       (procedure in GENSCRN.PRG)
  1389. *!               : GETWITHLIST        (procedure in GENSCRN.PRG)
  1390. *!
  1391. *!*****************************************************************************
  1392. FUNCTION openprojdbf
  1393. PARAMETER m.projdbf, m.recno
  1394.  
  1395. SELECT 0
  1396. IF USED("projdbf")
  1397.    m.g_projalias = "P"+SUBSTR(LOWER(SYS(3)),2,8)
  1398. ELSE
  1399.    m.g_projalias = "projdbf"
  1400. ENDIF
  1401. USE (m.projdbf) ALIAS (m.g_projalias)
  1402. DO notearea
  1403. IF versnum() > "2.5"
  1404.    SET NOCPTRANS TO devinfo, arranged, symbols, object
  1405. ENDIF
  1406. m.g_errlog = stripext(m.projdbf)
  1407. m.g_projpath = SUBSTR(m.projdbf,1,RAT("\",m.projdbf))
  1408.  
  1409. IF FCOUNT() <> c_pjxflds
  1410.    IF FCOUNT() = c_pjx20flds
  1411.       DO errorhandler WITH "Invalid 2.0 project file passed to GenScrn.",;
  1412.          LINENO(), c_error_2
  1413.    ELSE
  1414.       DO errorhandler WITH "Generator out of date.",;
  1415.          LINENO(), c_error_2
  1416.    ENDIF
  1417.    RETURN .F.
  1418. ENDIF
  1419.  
  1420. DO refreshprefs
  1421. GOTO m.recno
  1422. m.g_keyno        = setid
  1423. m.g_outfile      = ALLTRIM(SUBSTR(outfile,1,AT(c_null,outfile)-1))
  1424. m.g_outfile      = FULLPATH(m.g_outfile, m.g_projpath)
  1425. m.g_openfiles    = openfiles
  1426. m.g_closefiles   = closefiles
  1427. m.g_defwin       = defwinds
  1428. m.g_relwin       = relwinds
  1429. m.g_readcycle    = readcycle
  1430. m.g_readlock     = NOLOCK
  1431. m.g_readmodal    = MODAL
  1432. m.g_readborder   = nologo
  1433. m.g_multreads    = multreads
  1434. m.g_allplatforms = !savecode
  1435. DO getwithlist
  1436.  
  1437. *
  1438. * GETWITHLIST - Construct the list for READ level WITH clause.
  1439. *
  1440. *!*****************************************************************************
  1441. *!
  1442. *!      Procedure: GETWITHLIST
  1443. *!
  1444. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  1445. *!
  1446. *!*****************************************************************************
  1447. PROCEDURE getwithlist
  1448. PRIVATE m.start, m.cret, m.occurance, m.list
  1449. m.start = 1
  1450. m.occurance = 1
  1451. m.cret = AT(c_cret,assocwinds,m.occurance)
  1452. DO WHILE m.cret<>0
  1453.    m.list = ALLTRIM(SUBSTR(assocwinds,m.start,m.cret-m.start))
  1454.    m.g_withlist = m.g_withlist + ;
  1455.       IIF(EMPTY(m.g_withlist),"",", ") + m.list
  1456.    m.occurance = m.occurance + 1
  1457.    m.start = m.cret + 1
  1458.    m.cret = AT(c_cret,assocwinds,m.occurance)
  1459. ENDDO
  1460.  
  1461. *
  1462. * REFRESHPREFS - Refresh Documentation and Developer preferences.
  1463. *
  1464. * Description:
  1465. * Get the newest preferences for documentation style and developer
  1466. * data from the HEADER record.
  1467. *
  1468. *!*****************************************************************************
  1469. *!
  1470. *!      Procedure: REFRESHPREFS
  1471. *!
  1472. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  1473. *!
  1474. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  1475. *!               : SUBDEVINFO()       (function  in GENSCRN.PRG)
  1476. *!
  1477. *!*****************************************************************************
  1478. PROCEDURE refreshprefs
  1479. PRIVATE m.start
  1480. LOCATE FOR TYPE = "H"
  1481. IF NOT FOUND ()
  1482.    DO errorhandler WITH "Missing header record in "+m.projdbf,;
  1483.       LINENO(), c_error_2
  1484.    RETURN
  1485. ENDIF
  1486.  
  1487. m.g_homedir = ALLTRIM(SUBSTR(homedir,1,AT(c_null,homedir)-1))
  1488. IF RIGHT(m.g_homedir,1) <> "\"
  1489.    m.g_homedir = m.g_homedir + "\"
  1490. ENDIF
  1491.  
  1492. m.start = 1
  1493. m.g_devauthor = subdevinfo(m.start,c_authorlen,m.g_devauthor)
  1494.  
  1495. m.start = m.start + c_authorlen + 1
  1496. m.g_devcompany = subdevinfo(m.start,c_complen,m.g_devcompany)
  1497.  
  1498. m.start = m.start + c_complen + 1
  1499. m.g_devaddress = subdevinfo(m.start,c_addrlen,m.g_devaddress)
  1500.  
  1501. m.start = m.start + c_addrlen + 1
  1502. m.g_devcity = subdevinfo(m.start,c_citylen,m.g_devcity)
  1503.  
  1504. m.start = m.start + c_citylen + 1
  1505. m.g_devstate = subdevinfo(m.start,c_statlen,m.g_devstate)
  1506.  
  1507. m.start = m.start + c_statlen + 1
  1508. m.g_devzip = subdevinfo(m.start,c_ziplen,m.g_devzip)
  1509.  
  1510. m.start = m.start + c_ziplen + 1
  1511. m.g_devctry = subdevinfo(m.start,c_countrylen,m.g_devctry)
  1512.  
  1513. IF cmntstyle = 0
  1514. *  m.g_corn1 = "╓"
  1515.    m.g_corn1 = "*"
  1516. *  m.g_corn2 = "╖"
  1517.    m.g_corn2 = "*"
  1518. *  m.g_corn3 = "╙"
  1519.    m.g_corn3 = "*"
  1520. *  m.g_corn4 = "╜"
  1521.    m.g_corn4 = "*"
  1522. *  m.g_corn5 = "╟"
  1523.    m.g_corn5 = "*"
  1524. *  m.g_corn6 = "╢"
  1525.    m.g_corn6 = "*"
  1526. *  m.g_horiz = "─"
  1527.    m.g_horiz = "*"
  1528. *  m.g_verti1 = "║"
  1529.    m.g_verti1 = "*"
  1530. *  m.g_verti2= "║"
  1531.    m.g_verti2= "*"
  1532. ENDIF
  1533.  
  1534. *
  1535. * SUBDEVINFO - Extract strings from the DEVINFO memo field.
  1536. *
  1537. *!*****************************************************************************
  1538. *!
  1539. *!       Function: SUBDEVINFO
  1540. *!
  1541. *!      Called by: REFRESHPREFS       (procedure in GENSCRN.PRG)
  1542. *!
  1543. *!*****************************************************************************
  1544. FUNCTION subdevinfo
  1545. PARAMETER m.start, m.stop, m.default
  1546. PRIVATE m.string
  1547. m.string = SUBSTR(devinfo, m.start, m.stop+1)
  1548. m.string = SUBSTR(m.string, 1, AT(c_null,m.string)-1)
  1549. RETURN IIF(EMPTY(m.string), m.default, m.string)
  1550.  
  1551. **
  1552. ** High Level Controlling Structures in Format file generation.
  1553. **
  1554.  
  1555. *
  1556. * BUILD - Controlling procedure for building of a format file.
  1557. *
  1558. * Description:
  1559. * This procedure is a controlling procedure for the process of
  1560. * generating a screen file.  It enables building, activates the
  1561. * thermometer, calls BUILDCTRL and combines two output files,
  1562. * and finally disables building.
  1563. * This procedure also makes calls to UPDTHERM to
  1564. * update the thermometer display.
  1565. *
  1566. *!*****************************************************************************
  1567. *!
  1568. *!      Procedure: BUILD
  1569. *!
  1570. *!      Called by: GENSCRN.PRG
  1571. *!
  1572. *!          Calls: BUILDENABLE        (procedure in GENSCRN.PRG)
  1573. *!               : ACTTHERM           (procedure in GENSCRN.PRG)
  1574. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1575. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1576. *!               : COMBINE            (procedure in GENSCRN.PRG)
  1577. *!               : BUILDDISABLE       (procedure in GENSCRN.PRG)
  1578. *!               : DEACTTHERMO        (procedure in GENSCRN.PRG)
  1579. *!
  1580. *!*****************************************************************************
  1581. PROCEDURE BUILD
  1582.  
  1583. DO buildenable
  1584. DO acttherm WITH "Generating Screen Code..."
  1585. DO updtherm WITH 5
  1586.  
  1587. DO dispatchbuild
  1588.  
  1589. DO updtherm WITH  95 * m.g_numplatforms
  1590. DO combine
  1591. DO updtherm WITH 100 * m.g_numplatforms   && force thermometer to complete
  1592. DO builddisable
  1593.  
  1594. DO deactthermo
  1595.  
  1596. *
  1597. * DISPATCHBUILD - Determines which platforms are to be generated and
  1598. *                  calls BUILDCTRL for each one.
  1599. *
  1600. *!*****************************************************************************
  1601. *!
  1602. *!      Procedure: DISPATCHBUILD
  1603. *!
  1604. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  1605. *!
  1606. *!          Calls: COUNTPLATFORMS     (procedure in GENSCRN.PRG)
  1607. *!               : PREPPARAMS         (procedure in GENSCRN.PRG)
  1608. *!               : MULTIPLAT()        (function  in GENSCRN.PRG)
  1609. *!               : SCANPROC           (procedure in GENSCRN.PRG)
  1610. *!               : GENPARAMETER       (procedure in GENSCRN.PRG)
  1611. *!               : LOOKUPPLATFORM     (procedure in GENSCRN.PRG)
  1612. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  1613. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  1614. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  1615. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  1616. *!               : NEWWINDOWS()       (function  in GENSCRN.PRG)
  1617. *!               : NEWDBFS()          (function  in GENSCRN.PRG)
  1618. *!               : NEWREADCLAUSES     (procedure in GENSCRN.PRG)
  1619. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  1620. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  1621. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  1622. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1623. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  1624. *!
  1625. *!*****************************************************************************
  1626. PROCEDURE dispatchbuild
  1627. PRIVATE m.i, m.thisplat, m.j
  1628. m.g_numplatforms = countplatforms()
  1629.  
  1630. DO prepparams
  1631.  
  1632. _TEXT = m.g_orghandle
  1633. _PRETEXT = ""
  1634.  
  1635. DO CASE
  1636. CASE multiplat()
  1637.    * Emit code for all common platforms in the screen set and put CASE statements
  1638.    * around the code for each one.  The g_platforms array contains the list of
  1639.    * platforms to generate for.
  1640.  
  1641.    * If generating for multiple platforms, scan all cleanup snippets and assemble an
  1642.    * array of unique procedure names.  This process is designed to handle procedure name
  1643.    * collisions across platforms.
  1644.    DO scanproc
  1645.  
  1646.    DO header   && main heading at top of program
  1647.  
  1648.    * Special case when there are multiple platforms being sent to the
  1649.    * same SPR.  Since the SPR can only have a single parameter statement,
  1650.    * and since it has to appear before the CASE _platform code, put it
  1651.    * here.
  1652.    DO genparameter
  1653.  
  1654.    m.thisplat = "X"   && placeholder value
  1655.    m.i = 1
  1656.    DO WHILE !EMPTY(m.thisplat)
  1657.       m.thisplat = lookupplatform(m.i)
  1658.       IF !EMPTY(m.thisplat)
  1659.          DO putmsg WITH "Generating code for "+versioncap(m.thisplat)
  1660.  
  1661.          IF m.i = 1
  1662.             \DO CASE
  1663.          ELSE
  1664.             \
  1665.          ENDIF
  1666.          \CASE _<<m.thisplat>>
  1667.          \
  1668.  
  1669.          * Switch the platform to generate for
  1670.          m.g_genvers = m.thisplat
  1671.  
  1672.          * Update screen array entries for the new platform, unless it's the currently
  1673.          * executing platform, in which case we did this just above.
  1674.          IF !(m.thisplat == m.g_thisvers)
  1675.             * Start with a fresh set of screens.  Prepscreens() fills in the details.
  1676.             g_nscreens = 0
  1677.             IF !prepscreens(m.thisplat)
  1678.                DO errorhandler WITH "Error initializing screens for ";
  1679.                   +PROPER(m.thisplat)+".", LINENO(), c_error_3
  1680.                CANCEL
  1681.             ENDIF
  1682.             DO newwindows      && initialize the window array
  1683.             DO newdbfs         && initialize the DBF name array
  1684.             DO newreadclauses  && initialize the read clause variables
  1685.             DO newdirectives   && initialize the directives that change from platform to platform
  1686.             DO newschemes      && initialize the scheme variables
  1687.          ENDIF
  1688.  
  1689.          DO pushindent
  1690.          DO buildctrl WITH m.thisplat, m.i, .F.
  1691.          DO popindent
  1692.       ENDIF
  1693.       m.i = m.i + 1
  1694.    ENDDO
  1695.    \
  1696.    \ENDCASE
  1697.    \
  1698.    _TEXT = m.g_tmphandle
  1699.    m.thispretext = _PRETEXT
  1700.    _PRETEXT = ""
  1701.    DO updtherm WITH 70 * m.g_numplatforms
  1702.    DO genprocedures
  1703.    _TEXT = m.g_orghandle
  1704.    _PRETEXT = m.thispretext
  1705.  
  1706. OTHERWISE                         && just outputing one platform.
  1707.    * If we are generating for a platform other than the one we are running
  1708.    * on, run through prepscreens again to assign the right platform
  1709.    * name to each of these screens.
  1710.    IF (_DOS AND g_platforms[1] <> "DOS") ;
  1711.          OR (_WINDOWS AND g_platforms[1] <> "WINDOWS") ;
  1712.          OR (_MAC AND g_platforms[1] <> "MAC") ;
  1713.          OR (_UNIX AND g_platforms[1] <> "UNIX")
  1714.       g_nscreens = 0
  1715.       IF !prepscreens(g_platforms[1])
  1716.          DO errorhandler WITH "Error initializing screens for ";
  1717.             +PROPER(m.thisplat)+".", LINENO(), c_error_3
  1718.          CANCEL
  1719.       ENDIF
  1720.    ENDIF
  1721.  
  1722.    m.g_allplatforms = .F.
  1723.    m.g_numplatforms = 1
  1724.    m.g_genvers      = g_platforms[1]
  1725.  
  1726.    DO newwindows      && Initialize the array of window names
  1727.    DO newdbfs         && Initialize the array of DBF names
  1728.    DO newreadclauses  && Initialize the read clause variables for each platform
  1729.    DO newdirectives   && Initialize the directives that change from platform to platform
  1730.    DO newschemes      && initialize the scheme variables
  1731.  
  1732.    DO header
  1733.    DO buildctrl WITH g_platforms[1], 1, .T.
  1734.  
  1735.    DO updtherm WITH  70
  1736.    DO genprocedures
  1737. ENDCASE
  1738.  
  1739.  
  1740. **
  1741. ** Code Associated With Building of the Control Program.
  1742. **
  1743. *
  1744. * BUILDCTRL - Generate Format control file.
  1745. *
  1746. * Description:
  1747. * Buildctrl controls the generation process.  It invokes procedures
  1748. * which build the output program from a set of screens.
  1749. *
  1750. *!*****************************************************************************
  1751. *!
  1752. *!      Procedure: BUILDCTRL
  1753. *!
  1754. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1755. *!
  1756. *!          Calls: HEADER             (procedure in GENSCRN.PRG)
  1757. *!               : GENPARAMETER       (procedure in GENSCRN.PRG)
  1758. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  1759. *!               : GENSETENVIRON      (procedure in GENSCRN.PRG)
  1760. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  1761. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  1762. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  1763. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  1764. *!               : DEFPOPUPS          (procedure in GENSCRN.PRG)
  1765. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  1766. *!               : GENCLNENVIRON      (procedure in GENSCRN.PRG)
  1767. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  1768. *!
  1769. *!*****************************************************************************
  1770. PROCEDURE buildctrl
  1771. PARAMETERS m.pltfrm, m.pnum, m.putparam, m.dbalias
  1772. PRIVATE m.i
  1773.  
  1774. IF m.putparam
  1775.    * Bracketed code is handled elsewhere.  We are only emitting the parameter
  1776.    * from this platform.  Go get it again to make sure we have the right one.
  1777.    * At this point, g_parameter could contain the parameter from any platform.
  1778.  
  1779.    * Open the database for the first screen since it's the only one we can generate
  1780.    * a parameter statement for.
  1781.    m.dbalias = g_screens[1,5]
  1782.    SELECT (m.dbalias)
  1783.    DO seekheader WITH 1
  1784.  
  1785.    m.g_parameter = getparam("setupcode")
  1786.  
  1787.    DO genparameter
  1788. ENDIF
  1789. DO gensect1                                                     && SECTION 1 setup code
  1790. DO gensetenviron                                        && environment setup code
  1791. IF m.g_openfiles
  1792.    DO genopendbfs                                       && USE ... INDEX ... statements
  1793.    DO updtherm WITH 15 * m.pnum    && and SET RELATIONS
  1794. ENDIF
  1795.  
  1796. DO defwindows                                           && window definitions
  1797. DO gensect2                                                     && SECTION 2 setup code
  1798. DO defpopups                                            && lists
  1799. DO updtherm WITH 35 * m.pnum
  1800.  
  1801. DO buildfmt WITH m.pnum            && @ ... SAY/GET statements
  1802.  
  1803. DO updtherm WITH 60 * m.pnum
  1804. IF m.g_windows AND m.g_relwin AND !m.g_noread
  1805.    * If the READ is omitted, don't produce the code to release the window.
  1806.    FOR m.i = 1 TO m.g_nwindows
  1807.       \RELEASE WINDOW <<g_wndows[m.i,1]>>
  1808.    ENDFOR
  1809. ENDIF
  1810.  
  1811. IF m.g_moddesktop AND m.g_relwin AND INLIST(m.g_genvers,"WINDOWS","MAC")
  1812.    \MODIFY WINDOW SCREEN
  1813. ENDIF
  1814.  
  1815. DO genclnenviron                                    && environment cleanup code
  1816. DO updtherm WITH 65 * m.pnum
  1817. DO gencleanup                       && cleanup code, but not procedures/functions
  1818.  
  1819. *
  1820. * GENSETENVIRON - Generate environment code for the .SPR
  1821. *
  1822. *!*****************************************************************************
  1823. *!
  1824. *!      Procedure: GENSETENVIRON
  1825. *!
  1826. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1827. *!
  1828. *!*****************************************************************************
  1829. PROCEDURE gensetenviron
  1830. IF !m.g_noreadplain
  1831.    \
  1832.    \#REGION 0
  1833.    \REGIONAL m.currarea, m.talkstat, m.compstat
  1834.    \
  1835.    \IF SET("TALK") = "ON"
  1836.    \    SET TALK OFF
  1837.    \    m.talkstat = "ON"
  1838.    \ELSE
  1839.    \    m.talkstat = "OFF"
  1840.    \ENDIF
  1841.    \m.compstat = SET("COMPATIBLE")
  1842.    \SET COMPATIBLE FOXPLUS
  1843.  
  1844.    IF m.g_readborder AND (INLIST(m.g_genvers,"WINDOWS","MAC"))
  1845.       \
  1846.       \m.rborder = SET("READBORDER")
  1847.       \SET READBORDER ON
  1848.    ENDIF
  1849. ENDIF
  1850.  
  1851. IF m.g_closefiles
  1852.    \
  1853.    \m.currarea = SELECT()
  1854.    \
  1855. ENDIF
  1856.  
  1857. *
  1858. * GENCLNENVIRON - Generate environment code for the .SPR
  1859. *
  1860. *!*****************************************************************************
  1861. *!
  1862. *!      Procedure: GENCLNENVIRON
  1863. *!
  1864. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1865. *!
  1866. *!          Calls: GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  1867. *!               : RELPOPUPS          (procedure in GENSCRN.PRG)
  1868. *!
  1869. *!*****************************************************************************
  1870. PROCEDURE genclnenviron
  1871. IF m.g_closefiles
  1872.    DO genclosedbfs
  1873. ENDIF
  1874. IF m.g_somepops
  1875.    DO relpopups
  1876. ENDIF
  1877. IF !m.g_noreadplain
  1878.    \
  1879.    \#REGION 0
  1880.    IF m.g_readborder AND INLIST(m.g_genvers,"WINDOWS","MAC"))
  1881.       \
  1882.       \SET READBORDER &rborder
  1883.       \
  1884.    ENDIF
  1885.    \IF m.talkstat = "ON"
  1886.    \    SET TALK ON
  1887.    \ENDIF
  1888.    \IF m.compstat = "ON"
  1889.    \    SET COMPATIBLE ON
  1890.    \ENDIF
  1891.    \
  1892. ENDIF
  1893.  
  1894. *
  1895. * GENCLEANUP - Generate Cleanup Code.
  1896. *
  1897. *!*****************************************************************************
  1898. *!
  1899. *!      Procedure: GENCLEANUP
  1900. *!
  1901. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  1902. *!
  1903. *!          Calls: MULTIPLAT()        (function  in GENSCRN.PRG)
  1904. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  1905. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  1906. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  1907. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  1908. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  1909. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  1910. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  1911. *!
  1912. *!*****************************************************************************
  1913. PROCEDURE gencleanup
  1914. PRIVATE m.i, m.dbalias, m.msg
  1915.  
  1916. IF m.g_graphic
  1917.    m.msg = 'Generating Cleanup Code'
  1918.    IF multiplat()
  1919.       m.msg = m.msg + " for "+versioncap(m.g_genvers)
  1920.    ENDIF
  1921.    DO putmsg WITH  m.msg
  1922. ENDIF
  1923.  
  1924. * Generate the actual cleanup code--the code that precedes procedures
  1925. * and function declarations.
  1926. FOR m.i = 1 TO m.g_nscreens
  1927.    m.g_screen = m.i
  1928.    m.dbalias = g_screens[m.i,5]
  1929.    SELECT (m.dbalias)
  1930.  
  1931.    DO seekheader WITH m.i
  1932.    IF EMPTY (proccode)
  1933.       g_firstproc[m.i] = 0
  1934.       LOOP
  1935.    ENDIF
  1936.  
  1937.    * Find the line number where the first procedure or function
  1938.    * declaration occurs
  1939.    g_firstproc[m.i] = getfirstproc("PROCCODE")
  1940.  
  1941.    IF g_firstproc[m.i] <> 1
  1942.       * Either there aren't any procedures/functions, or they
  1943.       * are below the actual cleanup code.  Emit the cleanup code.
  1944.       DO commentblock WITH g_screens[m.i,1], " Cleanup Code"
  1945.       \#REGION <<INT(m.i)>>
  1946.       DO writecode WITH proccode, getplatname(m.i), c_fromone, g_firstproc[m.i], m.i
  1947.    ENDIF
  1948. ENDFOR
  1949. m.g_screen = 0
  1950.  
  1951. RETURN
  1952.  
  1953. *
  1954. * GENPROCEDURES - Generate Procedures and Functions from cleanup code.
  1955. *
  1956. *!*****************************************************************************
  1957. *!
  1958. *!      Procedure: GENPROCEDURES
  1959. *!
  1960. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  1961. *!
  1962. *!          Calls: PUTMSG             (procedure in GENSCRN.PRG)
  1963. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  1964. *!               : PUTPROCHEAD        (procedure in GENSCRN.PRG)
  1965. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  1966. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  1967. *!               : MULTIPLAT()        (function  in GENSCRN.PRG)
  1968. *!               : ISGENPLAT()        (function  in GENSCRN.PRG)
  1969. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  1970. *!
  1971. *!*****************************************************************************
  1972. PROCEDURE genprocedures
  1973. PRIVATE m.i, m.dbalias
  1974. m.msg = 'Generating Procedures and Functions'
  1975. DO putmsg WITH m.msg
  1976.  
  1977. * Go back through each of the screens and output any procedures and
  1978. * functions that are in the cleanup snippet.
  1979. FOR m.i = 1 TO m.g_nscreens
  1980.    m.g_screen = m.i
  1981.    m.g_isfirstproc = .T.  && reset this for each screen
  1982.    m.dbalias = g_screens[m.i,5]
  1983.    SELECT (m.dbalias)
  1984.    DO seekheader WITH m.i
  1985.  
  1986.    DO CASE
  1987.    CASE g_screens[m.i,6]    && DOS 2.0 screen
  1988.       IF g_firstproc[m.i] > 0
  1989.          DO putprochead WITH m.i, g_screens[m.i,1]
  1990.          DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  1991.       ENDIF
  1992.    CASE multiplat()
  1993.       * Multiple 2.5 platforms
  1994.       IF m.g_procsmatch   && all cleanup snippets in the file are the same
  1995.          * Get all the screen/platform headers from this screen file
  1996.          IF g_firstproc[m.i] > 0
  1997.             DO putprochead WITH m.i, g_screens[m.i,1]
  1998.             DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  1999.          ENDIF
  2000.       ELSE
  2001.          * The are some differences.  Look for procedure name collisions among the
  2002.          * cleanup snippets in the platforms we are generating.
  2003.          SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  2004.             IF EMPTY(proccode)
  2005.                LOOP
  2006.             ENDIF
  2007.             DO putprochead WITH m.i, g_screens[m.i,1]
  2008.             DO extractprocs WITH m.i
  2009.          ENDSCAN
  2010.       ENDIF
  2011.    OTHERWISE  && just generating one 2.5 platform
  2012.       IF g_firstproc[m.i] > 0
  2013.          DO putprochead WITH m.i, g_screens[m.i,1]
  2014.          DO writecode WITH proccode, getplatname(m.i), g_firstproc[m.i], c_untilend, m.i
  2015.       ENDIF
  2016.    ENDCASE
  2017. ENDFOR
  2018. m.g_screen = 0
  2019. RETURN
  2020.  
  2021. *
  2022. * PROCSMATCH - Are the CRCs for the cleanup snippets the same for all platforms in the
  2023. *                current screen that are being generated?
  2024. *
  2025. *!*****************************************************************************
  2026. *!
  2027. *!       Function: PROCSMATCH
  2028. *!
  2029. *!      Called by: SCANPROC           (procedure in GENSCRN.PRG)
  2030. *!
  2031. *!          Calls: ISGENPLAT()        (function  in GENSCRN.PRG)
  2032. *!
  2033. *!*****************************************************************************
  2034. FUNCTION procsmatch
  2035. PRIVATE m.crccode, m.thiscode, m.in_rec
  2036.  
  2037. m.in_rec = IIF(!EOF(),RECNO(),1)
  2038. m.crccode = "0"
  2039. * Get the headers for all the platforms we are generating
  2040. SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  2041.    m.thiscode = ALLTRIM(SYS(2007,proccode))
  2042.    DO CASE
  2043.    CASE m.crccode = "0"
  2044.       m.crccode = m.thiscode
  2045.    CASE m.thiscode <> m.crccode AND m.crccode <> "0"
  2046.       RETURN .F.
  2047.    ENDCASE
  2048. ENDSCAN
  2049. GOTO m.in_rec
  2050. RETURN .T.
  2051.  
  2052. *
  2053. * ISGENPLAT - Is this platform one of the ones being generated?
  2054. *
  2055. *!*****************************************************************************
  2056. *!
  2057. *!       Function: ISGENPLAT
  2058. *!
  2059. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  2060. *!               : PROCSMATCH()       (function  in GENSCRN.PRG)
  2061. *!               : SCANPROC           (procedure in GENSCRN.PRG)
  2062. *!
  2063. *!*****************************************************************************
  2064. FUNCTION isgenplat
  2065. PARAMETER m.platname
  2066. RETURN IIF(ASCAN(g_platforms,ALLTRIM(UPPER(m.platname))) > 0, .T. , .F. )
  2067.  
  2068. *
  2069. * PUTPROCHEAD - Emit the procedure and function heading if we haven't done
  2070. *
  2071. *!*****************************************************************************
  2072. *!
  2073. *!      Procedure: PUTPROCHEAD
  2074. *!
  2075. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  2076. *!
  2077. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  2078. *!
  2079. *!*****************************************************************************
  2080. PROCEDURE putprochead
  2081. PARAMETER m.scrnno, m.filname
  2082. IF m.g_isfirstproc
  2083.    \
  2084.    DO commentblock WITH g_screens[m.scrnno,1], " Supporting Procedures and Functions "
  2085.    \#REGION <<INT(m.scrnno)>>
  2086.    m.g_isfirstproc = .F.
  2087. ENDIF
  2088. RETURN
  2089.  
  2090. *
  2091. * EXTRACTPROCS - Output the procedures for the current platform in the current screen
  2092. *
  2093. *!*****************************************************************************
  2094. *!
  2095. *!      Procedure: EXTRACTPROCS
  2096. *!
  2097. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  2098. *!
  2099. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2100. *!               : MATCH()            (function  in GENSCRN.PRG)
  2101. *!               : GETPROCNUM()       (function  in GENSCRN.PRG)
  2102. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  2103. *!               : HASCONFLICT()      (function  in GENSCRN.PRG)
  2104. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  2105. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  2106. *!               : PROCCOMMENTBLOCK   (procedure in GENSCRN.PRG)
  2107. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  2108. *!
  2109. *!*****************************************************************************
  2110. PROCEDURE extractprocs
  2111. * We only get here if we are emitting for multiple platforms and the cleanup snippets
  2112. * for all platforms are not identical.  We are positioned on a screen header record for
  2113. * the g_genvers platform.
  2114. PARAMETER m.scrnno
  2115.  
  2116. PRIVATE m.hascontin, m.iscontin, m.sniplen, m.i, m.thisline, m.pnum, m.word1, m.word2
  2117.  
  2118. _MLINE = 0
  2119. m.sniplen   = LEN(proccode)
  2120. m.numlines  = MEMLINES(proccode)
  2121. m.hascontin = .F.
  2122. DO WHILE _MLINE < m.sniplen
  2123.    m.thisline  = UPPER(ALLTRIM(MLINE(proccode,1, _MLINE)))
  2124.    m.iscontin  = m.hascontin
  2125.    m.hascontin = RIGHT(m.thisline,1) = ';'
  2126.    IF LEFT(m.thisline,1) $ "PF" AND !m.iscontin
  2127.       m.word1 = wordnum(m.thisline, 1)
  2128.       IF match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2129.          m.word2 = wordnum(m.thisline,2)
  2130.          * Does this procedure have a name conflict?
  2131.          m.pnum = getprocnum(m.word2)
  2132.          IF pnum > 0
  2133.             DO CASE
  2134.             CASE g_procs[m.pnum,C_MAXPLATFORMS+2]
  2135.                * This one has already been generated.  Skip past it now.
  2136.                DO emitproc WITH .F., m.thisline, m.sniplen, m.scrnno
  2137.                LOOP
  2138.             CASE hasconflict(pnum)
  2139.                * Name collision detected.  Output bracketed code for all platforms
  2140.                DO putmsg WITH "Generating code for procedure/function ";
  2141.                   +LOWER(g_procs[m.pnum,1])
  2142.                DO updtherm WITH (70 + (25/g_procnames) * m.pnum) * m.g_numplatforms
  2143.                DO proccommentblock WITH g_screens[m.scrnno,1], " "+PROPER(word1);
  2144.                   +" " + g_procs[m.pnum,1]
  2145.                DO emitbracket WITH m.pnum, m.scrnno
  2146.             OTHERWISE
  2147.                * This procedure has no name collision and has not been emitted yet.
  2148.                DO putmsg WITH "Generating code for procedure/function ";
  2149.                   +LOWER(g_procs[m.pnum,1])
  2150.                DO updtherm WITH (70 + (25/g_procnames) * m.pnum) * m.g_numplatforms
  2151.                DO proccommentblock WITH g_screens[m.scrnno,1], " "+PROPER(word1);
  2152.                   +" " + g_procs[m.pnum,1]
  2153.                DO emitproc WITH .T., m.thisline, m.sniplen, m.scrnno
  2154.             ENDCASE
  2155.             g_procs[pnum,C_MAXPLATFORMS+2] = .T.
  2156.          ENDIF
  2157.       ENDIF
  2158.    ENDIF
  2159. ENDDO
  2160. RETURN
  2161.  
  2162. *
  2163. * EMITPROC - Scan through the next procedure/function in the current cleanup snippet.
  2164. *            If dowrite is TRUE, emit the code as we go.  Otherwise, just skip over it
  2165. *            and advance _MLINE.
  2166. *
  2167. *!*****************************************************************************
  2168. *!
  2169. *!      Procedure: EMITPROC
  2170. *!
  2171. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2172. *!
  2173. *!          Calls: WRITELINE          (procedure in GENSCRN.PRG)
  2174. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  2175. *!               : MATCH()            (function  in GENSCRN.PRG)
  2176. *!
  2177. *!*****************************************************************************
  2178. PROCEDURE emitproc
  2179. * We are positioned on the PROCEDURE or FUNCTION line now and there isn't a name
  2180. * conflict.
  2181. PARAMETER m.dowrite, m.thisline, m.sniplen, m.scrnno
  2182. PRIVATE m.word1, m.word2, m.line, m.upline, m.done, m.lastmline, ;
  2183.    m.iscontin, m.hascontin
  2184. m.hascontin = .F.
  2185. m.done = .F.
  2186.  
  2187. * Write the PROCEDURE/FUNCTION statement
  2188. m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2189. IF m.dowrite    && actually emit the procedure?
  2190.    DO writeline WITH m.thisline, m.g_genvers, m.upline, m.scrnno
  2191. ENDIF
  2192.  
  2193. * Write the body of the procedure
  2194. DO WHILE !m.done AND _MLINE < m.sniplen
  2195.    m.lastmline = _MLINE          && note where this line started
  2196.  
  2197.    m.line = MLINE(proccode,1, _MLINE)
  2198.    m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2199.  
  2200.    m.iscontin = m.hascontin
  2201.    m.hascontin = RIGHT(m.upline,1) = ';'
  2202.    IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2203.       m.word1 = wordnum(m.upline, 1)
  2204.       IF match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2205.          done = .T.
  2206.          _MLINE = m.lastmline    && drop back one line and stop writing
  2207.          LOOP
  2208.       ENDIF
  2209.    ENDIF
  2210.  
  2211.    IF m.dowrite    && actually emit the procedure?
  2212.       DO writeline WITH m.line, m.g_genvers, m.upline, m.scrnno
  2213.    ENDIF
  2214.  
  2215. ENDDO
  2216. RETURN
  2217.  
  2218. *
  2219. * EMITBRACKET - Emit DO CASE/CASE _DOS brackets and call putproc to emit code for this procedure
  2220. *
  2221. *!*****************************************************************************
  2222. *!
  2223. *!      Procedure: EMITBRACKET
  2224. *!
  2225. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2226. *!
  2227. *!          Calls: PUSHINDENT         (procedure in GENSCRN.PRG)
  2228. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  2229. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  2230. *!
  2231. *!*****************************************************************************
  2232. PROCEDURE emitbracket
  2233. PARAMETER m.pnum, m.scrnno
  2234. PRIVATE m.word1, m.word2, m.line, m.upline, m.done, m.lastmline, ;
  2235.    m.iscontin, m.hascontin, m.i
  2236. m.hascontin = .F.
  2237. m.done = .F.
  2238. \
  2239. \PROCEDURE <<g_procs[m.pnum,1]>>
  2240. IF !EMPTY(g_procs[m.pnum,C_MAXPLATFORMS+3])
  2241.    \PARAMETERS <<g_procs[m.pnum,C_MAXPLATFORMS+3]>>
  2242. ENDIF
  2243. \DO CASE
  2244.  
  2245. * Peek ahead and get the parameter statement
  2246. FOR m.platnum = 1 TO c_maxplatforms
  2247.    IF g_procs[m.pnum,m.platnum+1] < 0
  2248.       * There was no procedure for this platform
  2249.       LOOP
  2250.    ENDIF
  2251.    \CASE <<"_"+g_platlist[m.platnum]>>
  2252.    DO pushindent
  2253.    DO putproc WITH m.platnum, m.pnum, m.scrnno
  2254.    DO popindent
  2255. ENDFOR
  2256. \ENDCASE
  2257. RETURN
  2258.  
  2259. *
  2260. * PUTPROC - Write actual code for procedure procnum in platform platnum
  2261. *
  2262. *!*****************************************************************************
  2263. *!
  2264. *!      Procedure: PUTPROC
  2265. *!
  2266. *!      Called by: EMITBRACKET        (procedure in GENSCRN.PRG)
  2267. *!
  2268. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2269. *!               : MATCH()            (function  in GENSCRN.PRG)
  2270. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2271. *!
  2272. *!*****************************************************************************
  2273. PROCEDURE putproc
  2274. PARAMETER m.platnum, m.procnum, m.scrnno
  2275. PRIVATE m.in_rec, m.oldmine, m.done, m.line, m.upline, m.iscontin, m.hascontin, ;
  2276.    m.word1, m.word2
  2277.  
  2278. m.in_rec    = RECNO()
  2279. * Store the _MLINE position in the original snippet
  2280. m.oldmline  = _MLINE
  2281. m.hascontin = .F.       && the previous line was not a continuation line.
  2282. LOCATE FOR platform = g_platlist[m.platnum] AND objtype = c_otscreen
  2283. IF FOUND()
  2284.    * go to the PROCEDURE/FUNCTION statement
  2285.    _MLINE = g_procs[m.procnum,m.platnum+1]
  2286.    * Skip the PROCEDURE line, since we've already output one.
  2287.    m.line = MLINE(proccode,1, _MLINE)
  2288.  
  2289.    * We are now positioned at the line following the procedure statement.
  2290.    * Write until the end of the snippet or the next procedure.
  2291.    m.done = .F.
  2292.    DO WHILE !m.done
  2293.       m.line = MLINE(proccode,1, _MLINE)
  2294.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2295.       m.iscontin = m.hascontin
  2296.       m.hascontin = RIGHT(m.upline,1) = ';'
  2297.       IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2298.          m.word1 = wordnum(m.upline, 1)
  2299.          IF RIGHT(m.word1,1) = ';'
  2300.             m.word1 = LEFT(m.word1,LEN(m.word1)-1)
  2301.          ENDIF
  2302.  
  2303.          DO CASE
  2304.          CASE match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2305.             * Stop when we encounter the next snippet
  2306.             m.done = .T.
  2307.             LOOP
  2308.          CASE match(m.word1,"PARAMETERS")
  2309.             * Don't output it, but keep scanning for other code
  2310.             DO WHILE m.hascontin
  2311.                m.line = MLINE(proccode,1, _MLINE)
  2312.                m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2313.                m.hascontin = RIGHT(m.upline,1) = ';'
  2314.             ENDDO
  2315.             LOOP
  2316.          ENDCASE
  2317.       ENDIF
  2318.  
  2319.       DO writeline WITH m.line, g_platlist[m.platnum], m.upline, m.scrnno
  2320.  
  2321.       * Stop if we've run out of snippet
  2322.       IF _MLINE >= LEN(proccode)
  2323.          m.done = .T.
  2324.       ENDIF
  2325.    ENDDO
  2326. ENDIF
  2327.  
  2328. GOTO m.in_rec
  2329. * Restore the _MLINE position in the main snippet we are outputing
  2330. _MLINE = m.oldmline
  2331.  
  2332. *
  2333. * GETPROCNUM - Return the g_procs array position of the procedure named pname
  2334. *
  2335. *!*****************************************************************************
  2336. *!
  2337. *!       Function: GETPROCNUM
  2338. *!
  2339. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2340. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2341. *!
  2342. *!*****************************************************************************
  2343. FUNCTION getprocnum
  2344. PARAMETER m.pname
  2345. PRIVATE m.i
  2346. FOR m.i = 1 TO g_procnames
  2347.    IF g_procs[m.i,1] == m.pname
  2348.       RETURN m.i
  2349.    ENDIF
  2350. ENDFOR
  2351. RETURN  0
  2352.  
  2353. *
  2354. * HASCONFLICT - Is there a name collision for procedure number num?
  2355. *
  2356. *!*****************************************************************************
  2357. *!
  2358. *!       Function: HASCONFLICT
  2359. *!
  2360. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  2361. *!
  2362. *!*****************************************************************************
  2363. FUNCTION hasconflict
  2364. PARAMETER m.num
  2365. PRIVATE m.i, m.cnt
  2366. m.cnt = 0
  2367. FOR m.i = 1 TO c_maxplatforms
  2368.    IF g_procs[m.num,m.i+1] > 0
  2369.       m.cnt = m.cnt +1
  2370.    ENDIF
  2371. ENDFOR
  2372. RETURN IIF(m.cnt > 1,.T.,.F.)
  2373.  
  2374.  
  2375. *
  2376. * GETFIRSTPROC - Find first PROCEDURE or FUNCTION statement in a cleanup
  2377. *                snippet and return the line number on which it occurs.
  2378. *
  2379. *!*****************************************************************************
  2380. *!
  2381. *!       Function: GETFIRSTPROC
  2382. *!
  2383. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  2384. *!
  2385. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  2386. *!               : MATCH()            (function  in GENSCRN.PRG)
  2387. *!
  2388. *!*****************************************************************************
  2389. FUNCTION getfirstproc
  2390. PARAMETER m.snipname
  2391. PRIVATE proclineno, numlines, word1, first_space
  2392. _MLINE = 0
  2393. m.numlines = MEMLINES(&snipname)
  2394. FOR m.proclineno = 1 TO m.numlines
  2395.    m.line  = MLINE(&snipname, 1, _MLINE)
  2396.    m.line  = UPPER(LTRIM(m.line))
  2397.    m.word1 = wordnum(m.line,1)
  2398.    IF !EMPTY(m.word1) AND (match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION"))
  2399.       RETURN m.proclineno
  2400.    ENDIF
  2401. ENDFOR
  2402. RETURN 0
  2403.  
  2404. *
  2405. * SCANPROC - Find unique procedure names in cleanup snippets for all platforms
  2406. *
  2407. *!*****************************************************************************
  2408. *!
  2409. *!      Procedure: SCANPROC
  2410. *!
  2411. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  2412. *!
  2413. *!          Calls: PROCSMATCH()       (function  in GENSCRN.PRG)
  2414. *!               : ISGENPLAT()        (function  in GENSCRN.PRG)
  2415. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2416. *!
  2417. *!*****************************************************************************
  2418. PROCEDURE scanproc
  2419. PRIVATE m.in_rec
  2420. * See if all the cleanup snippets are the same.  If so, stop now.
  2421. m.g_procsmatch = procsmatch()
  2422. IF !m.g_procsmatch
  2423.    FOR m.g_screen = 1 TO m.g_nscreens
  2424.       m.dbalias = g_screens[m.g_screen,5]
  2425.       SELECT (m.dbalias)
  2426.  
  2427.       IF !g_screens[m.g_screen,6]      && not applicable for FoxPro 2.0 screens
  2428.          SCAN FOR objtype = c_otscreen AND isgenplat(platform)
  2429.             DO updprocarray
  2430.          ENDSCAN
  2431.       ENDIF
  2432.    ENDFOR
  2433.    m.g_screen = 0
  2434. ENDIF
  2435. RETURN
  2436.  
  2437. *
  2438. * UPDPROCARRAY - Pick out the procedures names in the current cleanup snippet and call
  2439. *                  AddProcName to update the g_procs array.
  2440. *
  2441. *!*****************************************************************************
  2442. *!
  2443. *!      Procedure: UPDPROCARRAY
  2444. *!
  2445. *!      Called by: SCANPROC           (procedure in GENSCRN.PRG)
  2446. *!
  2447. *!          Calls: VERSIONCAP()       (function  in GENSCRN.PRG)
  2448. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  2449. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  2450. *!               : MATCH()            (function  in GENSCRN.PRG)
  2451. *!               : ADDPROCNAME        (procedure in GENSCRN.PRG)
  2452. *!               : GETPROCNUM()       (function  in GENSCRN.PRG)
  2453. *!               : CLEANPARAM()       (function  in GENSCRN.PRG)
  2454. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  2455. *!
  2456. *!*****************************************************************************
  2457. PROCEDURE updprocarray
  2458. PRIVATE m.i, m.numlines, m.line, m.upline, m.word1, m.word2, m.iscontin, m.hascontin, ;
  2459.    m.lastmline, m.thisproc
  2460.  
  2461. DO putmsg WITH "Scanning cleanup snippet for ";
  2462.    +versioncap( IIF(TYPE("platform")<>"U",platform,"DOS") )
  2463.  
  2464. _MLINE = 0
  2465. m.numlines = MEMLINES(proccode)
  2466. m.hascontin = .F.
  2467. FOR m.i = 1 TO m.numlines
  2468.    m.lastmline = _MLINE                && note starting position of this line
  2469.    m.line      = MLINE(proccode,1, _MLINE)
  2470.    m.upline    = UPPER(ALLTRIM(m.line))
  2471.    m.iscontin  = m.hascontin
  2472.    m.hascontin = RIGHT(m.upline,1) = ';'
  2473.    IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  2474.       m.word1 = CHRTRAN(wordnum(m.upline, 1),';','')
  2475.       DO CASE
  2476.       CASE match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  2477.          m.word2 = wordnum(m.upline,2)
  2478.          DO addprocname WITH m.word2, platform, m.i, m.lastmline
  2479.          m.lastproc = m.word2
  2480.       CASE match(m.word1,"PARAMETERS")
  2481.          * Associate this parameter statement with the last procedure or function
  2482.          m.thisproc = getprocnum(m.lastproc)
  2483.          IF m.thisproc > 0
  2484.             m.thisparam = ALLTRIM(SUBSTR(m.upline,AT(' ',m.upline)+1))
  2485.             * Deal with continued PARAMETER lines
  2486.             DO WHILE m.hascontin AND m.i <= m.numlines
  2487.                m.lastmline = _MLINE                && note the starting position of this line
  2488.                m.line   = MLINE(proccode,1, _MLINE)
  2489.                m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2490.                m.thisparam = ;
  2491.                   m.thisparam + CHR(13)+CHR(10) + m.line
  2492.                m.hascontin = RIGHT(m.upline,1) = ';'
  2493.                m.i = m.i + 1
  2494.             ENDDO
  2495.             * Make sure that this parameter matches any others we've seen for this function
  2496.             DO CASE
  2497.             CASE EMPTY(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2498.                * First occurrence, or one platform has a parameter statement and another doesn't
  2499.                g_procs[m.thisproc,C_MAXPLATFORMS+3] = m.thisparam
  2500.             CASE cleanparam(m.thisparam) == cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2501.                * It matches--do nothing
  2502.             CASE cleanparam(m.thisparam) = cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  2503.                * The new one is a superset of the existing one.  Use the longer one.
  2504.                g_procs[m.thisproc,C_MAXPLATFORMS+3] = m.thisparam
  2505.             CASE cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3]) = cleanparam(m.thisparam)
  2506.                * The old one is a superset of the new one.  Keep the longer one.
  2507.             OTHERWISE
  2508.                DO errorhandler WITH "Different parameters for "+g_procs[m.thisproc,1],;
  2509.                   LINENO(),c_error_3
  2510.             ENDCASE
  2511.          ENDIF
  2512.       ENDCASE
  2513.    ENDIF
  2514. ENDFOR
  2515. RETURN
  2516.  
  2517. *
  2518. * ADDPROCNAME - Update g_procs with pname data
  2519. *
  2520. *!*****************************************************************************
  2521. *!
  2522. *!      Procedure: ADDPROCNAME
  2523. *!
  2524. *!      Called by: UPDPROCARRAY       (procedure in GENSCRN.PRG)
  2525. *!
  2526. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  2527. *!
  2528. *!*****************************************************************************
  2529. PROCEDURE addprocname
  2530. PARAMETER m.pname, m.platname, m.linenum, m.lastmline
  2531. PRIVATE m.rnum, m.platformcol, m.i, m.j
  2532. IF EMPTY(m.pname)
  2533.    RETURN
  2534. ENDIF
  2535.  
  2536. * Look up this name in the procedures array
  2537. m.rnum = 0
  2538. FOR m.i = 1 TO m.g_procnames
  2539.    IF g_procs[m.i,1] == m.pname
  2540.       m.rnum = m.i
  2541.       EXIT
  2542.    ENDIF
  2543. ENDFOR
  2544.  
  2545. IF m.rnum = 0
  2546.    * New name
  2547.    g_procnames = m.g_procnames + 1
  2548.    DIMENSION g_procs[m.g_procnames,C_MAXPLATFORMS+3]
  2549.    g_procs[m.g_procnames,1] = UPPER(ALLTRIM(m.pname))
  2550.    FOR m.j = 1 TO c_maxplatforms
  2551.       g_procs[m.g_procnames,m.j + 1] = -1
  2552.    ENDFOR
  2553.    g_procs[m.g_procnames,C_MAXPLATFORMS+2] = .F.   && not emitted yet
  2554.    g_procs[m.g_procnames,C_MAXPLATFORMS+3] = ""    && parameter statement
  2555.    m.rnum = m.g_procnames
  2556. ENDIF
  2557.  
  2558. m.platformcol = getplatnum(m.platname) + 1
  2559. IF m.platformcol > 1
  2560.    g_procs[m.rnum, m.platformcol] = m.lastmline
  2561. ENDIF
  2562. RETURN
  2563.  
  2564. *
  2565. * GETPLATNUM - Return the g_platlist array index given a platform name
  2566. *
  2567. *!*****************************************************************************
  2568. *!
  2569. *!       Function: GETPLATNUM
  2570. *!
  2571. *!      Called by: PREPWNAMES         (procedure in GENSCRN.PRG)
  2572. *!               : ADDPROCNAME        (procedure in GENSCRN.PRG)
  2573. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2574. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2575. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  2576. *!
  2577. *!*****************************************************************************
  2578. FUNCTION getplatnum
  2579. PARAMETER m.platname
  2580. PRIVATE m.i
  2581. FOR m.i = 1 TO c_maxplatforms
  2582.    IF g_platlist[m.i] == UPPER(ALLTRIM(m.platname))
  2583.       RETURN m.i
  2584.    ENDIF
  2585. ENDFOR
  2586. RETURN 0
  2587.  
  2588. *
  2589. * GENPARAMETER - Generate the PARAMETER statement
  2590. *
  2591. *!*****************************************************************************
  2592. *!
  2593. *!      Procedure: GENPARAMETER
  2594. *!
  2595. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  2596. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  2597. *!
  2598. *!*****************************************************************************
  2599. PROCEDURE genparameter
  2600. IF !EMPTY(m.g_parameter)
  2601.    \PARAMETERS <<m.g_parameter>>
  2602. ENDIF
  2603. RETURN
  2604.  
  2605. *
  2606. * GENSECT1 - Generate #SECTION 1 code for all screens.
  2607. *
  2608. *!*****************************************************************************
  2609. *!
  2610. *!      Procedure: GENSECT1
  2611. *!
  2612. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  2613. *!
  2614. *!          Calls: MULTIPLAT()        (function  in GENSCRN.PRG)
  2615. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  2616. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  2617. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  2618. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  2619. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  2620. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  2621. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2622. *!
  2623. *!*****************************************************************************
  2624. PROCEDURE gensect1
  2625. PRIVATE m.i, m.dbalias, m.string, m.loop, m.j, m.end, m.msg, m.thisline
  2626. m.msg =  'Generating Setup Code'
  2627. IF multiplat()
  2628.    m.msg = m.msg + " for "+versioncap(m.g_genvers)
  2629. ENDIF
  2630. DO putmsg WITH m.msg
  2631. m.string = " Setup Code - SECTION 1"
  2632.  
  2633. FOR m.i = 1 TO m.g_nscreens
  2634.    m.g_screen = m.i
  2635.  
  2636.    m.dbalias = g_screens[m.i,5]
  2637.    SELECT (m.dbalias)
  2638.    DO seekheader WITH m.i
  2639.    IF EMPTY (setupcode)
  2640.       LOOP
  2641.    ENDIF
  2642.  
  2643.    m.g_sect1start= c_fromone
  2644.    m.g_sect2start= c_untilend
  2645.    m.loop  = .F.
  2646.  
  2647.    IF ATCLINE("#SECT", setupcode) <> 0
  2648.       m.g_sect1start = findsection(1, setupcode)+1
  2649.       m.g_sect2start = findsection(2, setupcode)
  2650.    ENDIF
  2651.  
  2652.    DO notedirectives WITH (m.i)
  2653.  
  2654.    * See if there are nondirective statements in SECTION 1
  2655.    IF m.g_sect2start-m.g_sect1start <= 3
  2656.       IF m.g_sect2start = 0
  2657.          m.end = MEMLINES(setupcode)
  2658.       ELSE
  2659.          m.end = m.g_sect2start-1
  2660.       ENDIF
  2661.       m.loop = .T.
  2662.       m.j = m.g_sect1start
  2663.       DO WHILE m.j <= m.end
  2664.          m.thisline = MLINE(setupcode,m.j)
  2665.          IF AT('#',m.thisline) <> 1 OR AT('#INSE',m.thisline) = 1
  2666.             m.loop = .F.
  2667.             EXIT
  2668.          ENDIF
  2669.          m.j = m.j + 1
  2670.       ENDDO
  2671.    ENDIF
  2672.    IF m.loop
  2673.       LOOP
  2674.    ENDIF
  2675.    IF NOT (m.g_sect1start=1 OR (m.g_sect1start=m.g_sect2start) OR ;
  2676.          (m.g_sect2start<>0 AND m.g_sect1start>m.g_sect2start))
  2677.  
  2678.       DO commentblock WITH g_screens[m.i,1], m.string
  2679.       \#REGION <<INT(m.i)>>
  2680.       _MLINE = 0
  2681.       DO writecode WITH setupcode, getplatname(m.i), m.g_sect1start, m.g_sect2start, m.i, 'setup'
  2682.    ENDIF
  2683. ENDFOR
  2684. m.g_screen = 0
  2685.  
  2686. *
  2687. * GENSECT2 - Generate Setup code #SECTION 2.
  2688. *
  2689. *!*****************************************************************************
  2690. *!
  2691. *!      Procedure: GENSECT2
  2692. *!
  2693. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  2694. *!
  2695. *!          Calls: SEEKHEADER         (procedure in GENSCRN.PRG)
  2696. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  2697. *!               : NOTEDIRECTIVES     (procedure in GENSCRN.PRG)
  2698. *!               : COUNTDIRECTIVES()  (function  in GENSCRN.PRG)
  2699. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  2700. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  2701. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2702. *!
  2703. *!*****************************************************************************
  2704. PROCEDURE gensect2
  2705. PRIVATE m.i, m.dbalias, m.string, m.endline, m.srtline, ;
  2706.    m.linecnt, m.lcnt, m.sect1, m.sect2
  2707. m.string = " Setup Code - SECTION 2"
  2708.  
  2709. FOR m.i = 1 TO m.g_nscreens
  2710.    m.g_screen = m.i
  2711.    m.dbalias = g_screens[m.i,5]
  2712.    SELECT (m.dbalias)
  2713.    DO seekheader WITH m.i
  2714.    IF EMPTY (setupcode)
  2715.       LOOP
  2716.    ENDIF
  2717.  
  2718.    m.g_sect1start= c_fromone
  2719.    m.g_sect2start= c_untilend
  2720.    m.loop  = .F.
  2721.  
  2722.    IF ATCLINE("#SECT", setupcode)<>0
  2723.       m.g_sect1start = findsection(1, setupcode)+1
  2724.       m.g_sect2start = findsection(2, setupcode)
  2725.    ENDIF
  2726.  
  2727.    m.sect1 = m.g_sect1start <> 0
  2728.    m.sect2 = m.g_sect2start <> 0
  2729.  
  2730.    DO notedirectives WITH (m.i)
  2731.    m.lcnt = countdirectives(m.sect1, m.sect2, m.i)
  2732.  
  2733.    IF m.g_sect2start = 0 AND m.g_sect1start > 1
  2734.       * No Section2 to emit
  2735.       LOOP
  2736.    ENDIF
  2737.  
  2738.    m.linecnt = MEMLINES(setupcode)
  2739.  
  2740.    IF m.linecnt > m.lcnt AND m.g_sect2start < m.linecnt
  2741.       DO commentblock WITH g_screens[m.i,1], m.string
  2742.       \#REGION <<INT(m.i)>>
  2743.       DO writecode WITH setupcode, getplatname(m.i), m.g_sect2start, c_untilend, m.i, 'setup'
  2744.    ENDIF
  2745. ENDFOR
  2746. m.g_screen = 0
  2747.  
  2748. *
  2749. * COUNTDIRECTIVES - Count directives in setup snippet.
  2750. *
  2751. *!*****************************************************************************
  2752. *!
  2753. *!       Function: COUNTDIRECTIVES
  2754. *!
  2755. *!      Called by: GENSECT2           (procedure in GENSCRN.PRG)
  2756. *!
  2757. *!*****************************************************************************
  2758. FUNCTION countdirectives
  2759. * This function counts the directives in setup.  It is used to figure out if there
  2760. * are any non-directive statements in the setup snippet.
  2761. PARAMETER m.sect1, m.sect2, m.scrnno
  2762. PRIVATE m.numlines, m.i, m.lcnt, m.thisline, m.upline
  2763. m.lcnt = 0
  2764. IF AT('#',setupcode) > 0
  2765.    * AT test is optimization to avoid processing the snippet when there are no directives
  2766.    m.numlines = MEMLINES(setupcode)
  2767.    _MLINE = 0
  2768.    FOR m.i = 1 TO m.numlines
  2769.       m.thisline = MLINE(setupcode, 1, _MLINE)
  2770.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2771.       IF LEFT(m.upline,1) = '#' AND !(LEFT(m.upline,5) = "#INSE")
  2772.          m.lcnt = m.lcnt + 1
  2773.       ENDIF
  2774.    ENDFOR
  2775. ENDIF
  2776. RETURN m.lcnt
  2777.  
  2778. *
  2779. * NOTEDIRECTIVES - Check for global directives such as #READCLAUSES, #NOREAD
  2780. *
  2781. *!*****************************************************************************
  2782. *!
  2783. *!      Procedure: NOTEDIRECTIVES
  2784. *!
  2785. *!      Called by: GENSECT2           (procedure in GENSCRN.PRG)
  2786. *!
  2787. *!*****************************************************************************
  2788. PROCEDURE notedirectives
  2789. * This function notes certain directives in the setup snippet and populates various
  2790. * global variables so that we don't have to keep going back to the snippet to find
  2791. * things.
  2792. PARAMETERS m.scrnno
  2793. PRIVATE m.numlines, m.i, m.thisline, m.upline
  2794. m.g_noread    = .F.
  2795. m.g_noreadplain = .F.
  2796. IF AT('#',setupcode) > 0
  2797.    * AT test is optimization to avoid processing the snippet when there are no directives
  2798.    m.numlines = MEMLINES(setupcode)
  2799.    _MLINE = 0
  2800.    FOR m.i = 1 TO m.numlines
  2801.       m.thisline = MLINE(setupcode, 1, _MLINE)
  2802.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.thisline,chr(9),' ')))
  2803.       IF LEFT(m.upline,1) = '#'
  2804.          DO CASE
  2805.          CASE LEFT(m.upline,5) = "#READ"   && #READCLAUSES - Additional READ clauses
  2806.             IF m.g_rddir = .F.
  2807.                m.g_rddir = .T.
  2808.                m.g_rddirno = m.scrnno
  2809.             ENDIF
  2810.          CASE LEFT(m.upline,5) = "#NORE"   && #NOREAD - omit the READ statement
  2811.             m.g_noread = .T.
  2812.             IF AT(m.g_dblampersand,m.upline) > 0
  2813.                m.upline = LEFT(m.upline,AT(m.g_dblampersand,m.upline)-1)
  2814.             ENDIF
  2815.             m.g_noreadplain = IIF(ATC(' PLAI',m.upline) > 0,.T.,.F.)
  2816.             IF m.g_noreadplain
  2817.                     m.g_openfiles    = .F.
  2818.                                         m.g_closefiles   = .F.
  2819.                                         m.g_defwin       = .F.
  2820.                                         m.g_relwin       = .F.
  2821.             ENDIF
  2822.          ENDCASE
  2823.       ENDIF
  2824.    ENDFOR
  2825. ENDIF
  2826.  
  2827. *
  2828. * FINDSECTION - Find #SECT... directive.
  2829. *
  2830. * Description:
  2831. * Locate and return the line on which the generator directive '#SECT'
  2832. * is located on.  If no valid directive found, return 0.
  2833. *
  2834. *!*****************************************************************************
  2835. *!
  2836. *!       Function: FINDSECTION
  2837. *!
  2838. *!      Called by: GENSECT1           (procedure in GENSCRN.PRG)
  2839. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  2840. *!
  2841. *!*****************************************************************************
  2842. FUNCTION findsection
  2843. PARAMETER m.sectionid, m.memo
  2844. PRIVATE m.line, m.linecnt, m.textline
  2845. m.line    = ATCLINE("#SECT", m.memo)
  2846. m.linecnt = MEMLINE(m.memo)
  2847. DO WHILE m.line <= m.linecnt
  2848.    m.textline = LTRIM(MLINE(m.memo, m.line))
  2849.    IF ATC("#SECT", m.textline)=1
  2850.       IF m.sectionid = 1
  2851.          IF AT("1", m.textline)<>0
  2852.             m.sect1 = .T.
  2853.             RETURN m.line
  2854.          ELSE
  2855.             RETURN 0
  2856.          ENDIF
  2857.       ELSE
  2858.          IF AT("2", m.textline)<>0
  2859.             m.sect2 = .T.
  2860.             RETURN m.line
  2861.          ENDIF
  2862.       ENDIF
  2863.    ENDIF
  2864.    m.line = m.line + 1
  2865. ENDDO
  2866. RETURN 0
  2867.  
  2868. *
  2869. * WRITECODE - Write contents of a memo to a low level file.
  2870. *
  2871. * Description:
  2872. * Receive a memo field as a parameter and write its contents out
  2873. * to the currently opened low level file whose handle is stored
  2874. * in the system memory variable _TEXT.  Contents of the system
  2875. * memory variable _PRETEXT will affect the positioning of the
  2876. * generated text.
  2877. *
  2878. *!*****************************************************************************
  2879. *!
  2880. *!      Procedure: WRITECODE
  2881. *!
  2882. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  2883. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  2884. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  2885. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  2886. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  2887. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  2888. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  2889. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  2890. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  2891. *!               : INSERTFILE         (procedure in GENSCRN.PRG)
  2892. *!
  2893. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  2894. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  2895. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  2896. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  2897. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  2898. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  2899. *!
  2900. *!*****************************************************************************
  2901. PROCEDURE writecode
  2902. PARAMETER m.memo, m.platname, m.start, m.end, m.scrnno, m.insetup
  2903. PRIVATE m.linecnt, m.i, m.line, m.upline, m.expr, m.platnum, m.at
  2904.  
  2905. _MLINE = 0
  2906.  
  2907. m.start = MAX(1,m.start)  && if zero, start at 1
  2908.  
  2909. IF m.end > m.start
  2910.    m.linecnt = m.end-1
  2911. ELSE
  2912.    m.linecnt = MEMLINES(m.memo)
  2913. ENDIF
  2914.  
  2915. m.platnum = getplatnum(m.platname)
  2916.  
  2917. FOR m.i = 1 TO m.start - 1
  2918.    m.line = MLINE(m.memo, 1, _MLINE)
  2919. ENDFOR
  2920.  
  2921. IF NOT EMPTY(m.insetup)
  2922.    FOR m.i = m.start TO m.linecnt
  2923.       m.line = MLINE(m.memo, 1, _MLINE)
  2924.       m.upline = UPPER(ALLTRIM(CHRTRAN(m.line,chr(9),' ')))
  2925.       IF !geninsertcode(@upline,m.scrnno, m.insetup, m.platname)
  2926.          m.isparam =  isparameter(@upline)
  2927.          DO CASE
  2928.          CASE m.isparam
  2929.             * Accumulate continuation line but don't output it.
  2930.             DO WHILE RIGHT(RTRIM(m.upline),1) = ';'
  2931.                m.line = MLINE(m.memo, 1, _MLINE)
  2932.                m.upline = m.upline + LTRIM(UPPER(m.line))
  2933.                m.i = m.i + 1
  2934.             ENDDO
  2935.          CASE AT('#',m.upline) <> 1 OR ;
  2936.                (AT('#READ', m.upline) <> 1 AND ;
  2937.                AT('#ITSE', m.upline) <> 1 AND ;
  2938.                AT('#WNAM', m.upline) <> 1 AND ;
  2939.                AT('#WCLA', m.upline) <> 1 AND ;
  2940.                AT('#REDE', m.upline) <> 1 AND ;
  2941.                AT('#NAME', m.upline) <> 1 AND ;
  2942.                AT('#NORE', m.upline) <> 1 AND ;
  2943.                AT('#SECT', m.upline) <> 1 AND ;
  2944.                AT('#TRAN', m.upline) <> 1 AND ;
  2945.                AT('#INSE', m.upline) <> 1)
  2946.             IF NOT EMPTY(g_wnames[m.scrnno,m.platnum])
  2947.                m.at = atwname(g_wnames[m.scrnno,m.platnum], m.line)
  2948.                IF m.at <> 0 AND !iscomment(@upline)
  2949.                   m.expr = STUFF(m.line, m.at, ;
  2950.                      LEN(g_wnames[m.scrnno,m.platnum]), ;
  2951.                      g_screens[m.scrnno,2])
  2952.                   \<<m.expr>>
  2953.                ELSE
  2954.                   \<<m.line>>
  2955.                ENDIF
  2956.             ELSE
  2957.                \<<m.line>>
  2958.             ENDIF
  2959.          ENDCASE
  2960.       ENDIF
  2961.    ENDFOR
  2962. ELSE   && not in setup
  2963.    FOR m.i = m.start TO m.linecnt
  2964.       m.line = MLINE(m.memo, 1, _MLINE)
  2965.       m.upline = UPPER(LTRIM(CHRTRAN(m.line,chr(9),' ')))
  2966.       DO writeline WITH m.line, m.platname, m.upline, m.scrnno
  2967.    ENDFOR
  2968. ENDIF
  2969. RETURN
  2970.  
  2971. *
  2972. * WRITELINE - Emit a single line
  2973. *
  2974. *!*****************************************************************************
  2975. *!
  2976. *!      Procedure: WRITELINE
  2977. *!
  2978. *!      Called by: EMITPROC           (procedure in GENSCRN.PRG)
  2979. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  2980. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  2981. *!
  2982. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  2983. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  2984. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  2985. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  2986. *!
  2987. *!*****************************************************************************
  2988. PROCEDURE writeline
  2989. PARAMETER m.line, m.platname, m.upline, m.scrnno
  2990.  
  2991. PRIVATE m.at, m.platnum, m.expr
  2992.  
  2993. IF g_screens[m.scrnno,6]   && DOS 2.0 screen
  2994.    m.platnum = getplatnum("DOS")
  2995. ELSE
  2996.    m.platnum = getplatnum(m.platname)
  2997. ENDIF
  2998.  
  2999. IF !geninsertcode(@upline, m.scrnno, .F., m.platname)   && by reference to save time
  3000.    IF !EMPTY(g_wnames[m.scrnno, m.platnum])
  3001.       m.at = atwname(g_wnames[m.scrnno, m.platnum], m.line)
  3002.       IF m.at <> 0 AND !iscomment(@upline)
  3003.          m.expr = STUFF(m.line, m.at, ;
  3004.             LEN(g_wnames[m.scrnno, m.platnum]), ;
  3005.             g_screens[m.scrnno,2])
  3006.          \<<m.expr>>
  3007.       ELSE
  3008.          IF !INLIST(LEFT(m.upline,2),"*!","*:") ;
  3009.                AND AT('#NAME', m.upline) <> 1
  3010.             \<<m.line>>
  3011.          ENDIF
  3012.       ENDIF
  3013.    ELSE
  3014.       IF !INLIST(LEFT(m.upline,2),"*!","*:") AND ATC('#NAME',m.upline) = 0
  3015.          \<<m.line>>
  3016.       ENDIF
  3017.    ENDIF
  3018. ENDIF
  3019. RETURN
  3020.  
  3021. *
  3022. * GENINSERTCODE - Emit code from the #insert file, if any
  3023. *
  3024. *!*****************************************************************************
  3025. *!
  3026. *!      Procedure: GENINSERTCODE
  3027. *!
  3028. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3029. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  3030. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  3031. *!
  3032. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  3033. *!               : INSERTFILE         (procedure in GENSCRN.PRG)
  3034. *!
  3035. *!*****************************************************************************
  3036. PROCEDURE geninsertcode
  3037. * Strg has to be trimmed before entering GenInsertCode.  It may be passed by reference.
  3038. PARAMETER m.strg, m.scrnno, m.insetup, m.platname
  3039. PRIVATE m.word1, m.filname
  3040. IF AT("#INSE",m.strg) = 1
  3041.    m.word1 = wordnum(m.strg,1)
  3042.    m.filname = SUBSTR(m.strg,LEN(m.word1)+1)
  3043.    m.filname = ALLTRIM(CHRTRAN(m.filname,CHR(9)," "))
  3044.    DO insertfile WITH m.filname, m.scrnno, m.insetup, m.platname
  3045.    RETURN .T.
  3046. ELSE
  3047.    RETURN .F.
  3048. ENDIF
  3049.  
  3050. *
  3051. * ISPARAMETER - Determine if strg is a PARAMETERS statement
  3052. *
  3053. *!*****************************************************************************
  3054. *!
  3055. *!       Function: ISPARAMETER
  3056. *!
  3057. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3058. *!
  3059. *!          Calls: MATCH()            (function  in GENSCRN.PRG)
  3060. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  3061. *!
  3062. *!*****************************************************************************
  3063. FUNCTION isparameter
  3064. PARAMETER m.strg
  3065. PRIVATE m.ispar
  3066. m.ispar = .F.
  3067. IF !EMPTY(strg) AND match(CHRTRAN(wordnum(strg,1),';',''),"PARAMETERS")
  3068.    m.ispar = .T.
  3069. ENDIF
  3070. RETURN m.ispar
  3071.  
  3072. *
  3073. * ATWNAME - Determine if valid m.string is in this line.
  3074. *
  3075. * Description:
  3076. * Make sure that if m.string is in fact the string we want to do
  3077. * the substitution on.
  3078. *
  3079. *!*****************************************************************************
  3080. *!
  3081. *!       Function: ATWNAME
  3082. *!
  3083. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3084. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  3085. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  3086. *!
  3087. *!*****************************************************************************
  3088. FUNCTION atwname
  3089. PARAMETER m.string, m.line
  3090. PRIVATE m.pos, m.before, m.after
  3091. m.pos = AT(m.string,m.line)
  3092. IF m.pos = 0
  3093.    RETURN 0
  3094. ENDIF
  3095. IF m.pos = 1
  3096.    m.pos = AT(m.string+" ",m.line)
  3097. ELSE
  3098.    IF m.pos = LEN(m.line) - LEN(m.string) + 1
  3099.       m.pos = AT(" "+m.string,m.line)
  3100.       m.pos = IIF(m.pos<>0, m.pos+1,m.pos)
  3101.    ELSE
  3102.       m.before = SUBSTR(m.line,m.pos-1,1)
  3103.  
  3104.       IF m.before = c_under OR ;
  3105.             (m.before >= '0' AND m.before <= '9') OR ;
  3106.             (m.before >= 'a' AND m.before <= 'z') OR ;
  3107.             (m.before >= 'A' AND m.before <= 'Z')
  3108.  
  3109.          RETURN 0
  3110.       ENDIF
  3111.       m.after = SUBSTR(m.line,m.pos+LEN(m.string),1)
  3112.  
  3113.       IF m.after = c_under OR ;
  3114.             (m.after >= '0' AND m.after <= '9') OR ;
  3115.             (m.after >= 'a' AND m.after <= 'z') OR ;
  3116.             (m.after >= 'A' AND m.after <= 'Z')
  3117.  
  3118.          RETURN 0
  3119.       ENDIF
  3120.    ENDIF
  3121. ENDIF
  3122. RETURN m.pos
  3123.  
  3124. *
  3125. * ISCOMMENT - Determine if textline is a comment line.
  3126. *
  3127. *!*****************************************************************************
  3128. *!
  3129. *!       Function: ISCOMMENT
  3130. *!
  3131. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  3132. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  3133. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  3134. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  3135. *!
  3136. *!*****************************************************************************
  3137. FUNCTION iscomment
  3138. PARAMETER m.textline
  3139. PRIVATE m.asterisk, m.isnote, m.ampersand, m.statement
  3140. IF EMPTY(m.textline)
  3141.    RETURN .F.
  3142. ENDIF
  3143. m.statement = UPPER(LTRIM(m.textline))
  3144.  
  3145. m.asterisk  = AT("*", m.statement)
  3146. m.ampersand = AT(m.g_dblampersand, m.statement)
  3147. m.isnote    = AT("NOTE", m.statement)
  3148.  
  3149. DO CASE
  3150. CASE (m.asterisk = 1 OR m.ampersand = 1)
  3151.    RETURN .T.
  3152. CASE (m.isnote = 1 ;
  3153.       AND (LEN(m.statement) <= 4 OR SUBSTR(m.statement,5,1) = ' '))
  3154.    * Don't be fooled by something like "notebook = 7"
  3155.    RETURN .T.
  3156. ENDCASE
  3157. RETURN .F.
  3158.  
  3159. *
  3160. * GENCLAUSECODE - Generate code for all read-level clauses.
  3161. *
  3162. * Description:
  3163. * Generate functions containing the code from each screen's
  3164. * READ level valid, show, when, activate, and deactivate clauses.
  3165. *
  3166. *!*****************************************************************************
  3167. *!
  3168. *!      Procedure: GENCLAUSECODE
  3169. *!
  3170. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  3171. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  3172. *!
  3173. *!          Calls: VALICLAUSE         (procedure in GENSCRN.PRG)
  3174. *!               : WHENCLAUSE         (procedure in GENSCRN.PRG)
  3175. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  3176. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  3177. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  3178. *!
  3179. *!*****************************************************************************
  3180. PROCEDURE genclausecode
  3181. PARAMETER m.screenno
  3182. DO valiclause WITH m.screenno
  3183. DO whenclause WITH m.screenno
  3184. DO acticlause WITH m.screenno
  3185. DO deatclause WITH m.screenno
  3186. DO showclause WITH m.screenno
  3187.  
  3188. *
  3189. * VALICLAUSE - Generate Read level Valid clause function.
  3190. *
  3191. * Description:
  3192. * Generate the function containing the code segment(s) provided
  3193. * by the user for the read level VALID clause.
  3194. * If multiple reads have been chosen, then this procedure generates
  3195. * a function for a single screen.
  3196. * If single read has been chosen and there are multiple screens,
  3197. * we will concatenate valid clause code segments form all screens
  3198. * to form a single function.
  3199. *
  3200. *!*****************************************************************************
  3201. *!
  3202. *!      Procedure: VALICLAUSE
  3203. *!
  3204. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3205. *!
  3206. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3207. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  3208. *!
  3209. *!*****************************************************************************
  3210. PROCEDURE valiclause
  3211. PARAMETER m.screenno
  3212. PRIVATE m.i, m.dbalias, m.thispretext
  3213.  
  3214. IF m.g_validtype = "EXPR" OR EMPTY(m.g_validtype)
  3215.    RETURN
  3216. ENDIF
  3217. DO genfuncheader WITH m.g_validname, "Read Level Valid", .T.
  3218. \FUNCTION <<m.g_validname>>     && Read Level Valid
  3219.  
  3220. m.thispretext = _PRETEXT
  3221. _PRETEXT = ""
  3222. IF m.g_multreads
  3223.    DO genvalidbody WITH m.screenno
  3224. ELSE
  3225.    FOR m.i = 1 TO m.g_nscreens
  3226.       m.g_screen = m.i
  3227.       m.dbalias = g_screens[m.i,5]
  3228.       SELECT (m.dbalias)
  3229.       DO genvalidbody WITH m.i
  3230.    ENDFOR
  3231.    m.g_screen = 0
  3232. ENDIF
  3233. _PRETEXT = m.thispretext
  3234.  
  3235. *
  3236. * GENVALIDBODY - Put out contents of a valid memo field.
  3237. *
  3238. *!*****************************************************************************
  3239. *!
  3240. *!      Procedure: GENVALIDBODY
  3241. *!
  3242. *!      Called by: VALICLAUSE         (procedure in GENSCRN.PRG)
  3243. *!
  3244. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  3245. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3246. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3247. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3248. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3249. *!
  3250. *!*****************************************************************************
  3251. PROCEDURE genvalidbody
  3252. PARAMETER m.region
  3253. PRIVATE m.name, m.pos
  3254.  
  3255. IF g_screens[m.region, 6]
  3256.    LOCATE FOR objtype = c_otscreen
  3257. ELSE
  3258.    LOCATE FOR platform = g_screens[m.region, 7] AND objtype = c_otscreen
  3259. ENDIF
  3260. IF NOT FOUND()
  3261.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3262.       LINENO(), c_error_3
  3263.    RETURN
  3264. ENDIF
  3265. IF NOT EMPTY(VALID) AND validtype<>0
  3266.    IF NOT m.g_multread
  3267.       m.name  = basename(DBF())
  3268.       DO gencomment WITH "Valid Code from screen: "+m.name
  3269.    ENDIF
  3270.    \#REGION <<INT(m.region)>>
  3271.    DO writecode WITH VALID, getplatname(m.region), c_fromone, c_untilend, m.region
  3272. ENDIF
  3273.  
  3274. *
  3275. * WHENCLAUSE - Generate Read level When clause function.
  3276. *
  3277. * Description:
  3278. * Generate the function containing the code segment(s) provided
  3279. * by the user for the read level WHEN clause.
  3280. * If multiple reads have been chosen, then this procedure generates
  3281. * a function for a single screen (i.e., the one it has been called for).
  3282. * If single read has been chosen and there are multiple screens,
  3283. * we will concatenate when clause code segments from all screens
  3284. * to form a single function.
  3285. *
  3286. *!*****************************************************************************
  3287. *!
  3288. *!      Procedure: WHENCLAUSE
  3289. *!
  3290. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3291. *!
  3292. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3293. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  3294. *!
  3295. *!*****************************************************************************
  3296. PROCEDURE whenclause
  3297. PARAMETER m.screenno
  3298. PRIVATE m.i, m.dbalias, m.thispretext
  3299.  
  3300. IF m.g_whentype = "EXPR" OR EMPTY(m.g_whentype)
  3301.    RETURN
  3302. ENDIF
  3303. DO genfuncheader WITH m.g_whenname, "Read Level When", .T.
  3304. \FUNCTION <<m.g_whenname>>     && Read Level When
  3305.  
  3306. m.thispretext = _PRETEXT
  3307. _PRETEXT = ""
  3308. IF m.g_multreads
  3309.    DO genwhenbody WITH m.screenno
  3310. ELSE
  3311.    FOR m.i = 1 TO m.g_nscreens
  3312.       m.g_screen = m.i
  3313.       m.dbalias = g_screens[m.i,5]
  3314.       SELECT (m.dbalias)
  3315.       DO genwhenbody WITH m.i
  3316.    ENDFOR
  3317.    m.g_screen = 0
  3318. ENDIF
  3319. _PRETEXT = m.thispretext
  3320.  
  3321. *
  3322. * GENWHENBODY - Put out contents of when memo field.
  3323. *
  3324. *!*****************************************************************************
  3325. *!
  3326. *!      Procedure: GENWHENBODY
  3327. *!
  3328. *!      Called by: WHENCLAUSE         (procedure in GENSCRN.PRG)
  3329. *!
  3330. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  3331. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3332. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3333. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3334. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3335. *!
  3336. *!*****************************************************************************
  3337. PROCEDURE genwhenbody
  3338. PARAMETER m.region
  3339. PRIVATE m.name, m.pos
  3340.  
  3341. IF g_screens[m.region, 6]
  3342.    LOCATE FOR objtype = c_otscreen
  3343. ELSE
  3344.    LOCATE FOR platform = g_screens[m.region, 7] AND objtype = c_otscreen
  3345. ENDIF
  3346. IF NOT FOUND()
  3347.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3348.       LINENO(), c_error_3
  3349.    RETURN
  3350. ENDIF
  3351.  
  3352. IF NOT EMPTY(WHEN) AND whentype<>0
  3353.    IF NOT m.g_multread
  3354.       m.name = basename(DBF())
  3355.       DO gencomment WITH "When Code from screen: "+m.name
  3356.    ENDIF
  3357.    \#REGION <<INT(m.region)>>
  3358.    DO writecode WITH WHEN, getplatname(m.region), c_fromone, c_untilend, m.region
  3359. ENDIF
  3360.  
  3361. *
  3362. * ACTICLAUSE - Generate Read level Activate clause function.
  3363. *
  3364. * Description:
  3365. * Generate the function containing the code segment(s) provided
  3366. * by the user for the read level ACTIVATE clause.
  3367. * If multiple reads have been chosen, then this procedure generates
  3368. * a function for a single screen (i.e., the one it has been called for).
  3369. * If single read has been chosen and there are multiple screens,
  3370. * we will concatenate activate clause code segments from all screens
  3371. * to form a single function.  Each individual screen's code
  3372. * segment will be enclosed in "IF WOUTPUT('windowname')" statement.
  3373. * Desk top will be represented by a null character. The above
  3374. * mentioned is performed by the procedure genactibody.
  3375. *
  3376. *!*****************************************************************************
  3377. *!
  3378. *!      Procedure: ACTICLAUSE
  3379. *!
  3380. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3381. *!
  3382. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3383. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3384. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3385. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3386. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3387. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3388. *!
  3389. *!*****************************************************************************
  3390. PROCEDURE acticlause
  3391. PARAMETER m.screenno
  3392. PRIVATE m.i, m.name
  3393.  
  3394. IF m.g_actitype = "EXPR" OR EMPTY(m.g_actitype)
  3395.    RETURN
  3396. ENDIF
  3397. DO genfuncheader WITH m.g_actiname, "Read Level Activate", .T.
  3398. \FUNCTION <<m.g_actiname>>     && Read Level Activate
  3399.  
  3400. IF m.g_multreads
  3401.    IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3402.       \#REGION <<INT(m.screenno)>>
  3403.       DO writecode WITH ACTIVATE, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3404.    ENDIF
  3405. ELSE
  3406.    FOR m.i = 1 TO m.g_nscreens
  3407.       m.g_screen = m.i
  3408.       m.dbalias = g_screens[m.i,5]
  3409.       SELECT (m.dbalias)
  3410.       IF g_screens[m.i, 6]
  3411.          LOCATE FOR objtype = c_otscreen
  3412.       ELSE
  3413.          LOCATE FOR platform = g_screens[m.i, 7] AND objtype = c_otscreen
  3414.       ENDIF
  3415.       IF NOT FOUND()
  3416.          DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3417.             LINENO(), c_error_3
  3418.          RETURN
  3419.       ENDIF
  3420.       IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3421.          m.name = basename(g_screens[m.i,1])
  3422.          DO gencomment WITH "Activate Code from screen: "+;
  3423.             m.name
  3424.       ENDIF
  3425.       IF NOT EMPTY(ACTIVATE) AND activtype<>0
  3426.          \#REGION <<INT(m.i)>>
  3427.          DO writecode WITH ACTIVATE, getplatname(m.i), c_fromone, c_untilend, m.i
  3428.       ENDIF
  3429.    ENDFOR
  3430.    m.g_screen = 0
  3431. ENDIF
  3432.  
  3433. *
  3434. * DEATCLAUSE - Generate Read level deactivate clause function.
  3435. *
  3436. * Description:
  3437. * Generate the function containing the code segment(s) provided
  3438. * by the user for the read level DEACTIVATE clause.
  3439. * If multiple reads have been chosen, then this procedure generates
  3440. * a function for a single screen (i.e., the one it has been called for).
  3441. * If single read has been chosen and there are multiple screens,
  3442. * we will concatenate deactivate clause code segments from all screens
  3443. * to form a single function.  Each individual screen's code
  3444. * segment will be enclosed in "IF WOUTPUT('windowname')" statement.
  3445. * Desk top will be represented by a null character. The above
  3446. * mentioned is performed by the procedure gendeatbody.
  3447. *
  3448. *!*****************************************************************************
  3449. *!
  3450. *!      Procedure: DEATCLAUSE
  3451. *!
  3452. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3453. *!
  3454. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3455. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3456. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3457. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3458. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3459. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3460. *!
  3461. *!*****************************************************************************
  3462. PROCEDURE deatclause
  3463. PARAMETER m.screenno
  3464. PRIVATE m.i, m.name
  3465.  
  3466. IF m.g_deattype = "EXPR" OR EMPTY(m.g_deattype)
  3467.    RETURN
  3468. ENDIF
  3469. DO genfuncheader WITH m.g_deatname, "Read Level Deactivate", .T.
  3470. \FUNCTION <<m.g_deatname>>     && Read Level Deactivate
  3471.  
  3472. IF m.g_multreads
  3473.    IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3474.       \#REGION <<INT(m.screenno)>>
  3475.       DO writecode WITH DEACTIVATE, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3476.    ENDIF
  3477. ELSE
  3478.    FOR m.i = 1 TO m.g_nscreens
  3479.       m.g_screen = m.i
  3480.       m.dbalias = g_screens[m.i,5]
  3481.       SELECT (m.dbalias)
  3482.       IF g_screens[m.i,6]
  3483.          LOCATE FOR objtype = c_otscreen
  3484.       ELSE
  3485.          LOCATE FOR platform = g_screens[m.i, 7] AND objtype = c_otscreen
  3486.       ENDIF
  3487.       IF NOT FOUND()
  3488.          DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  3489.             LINENO(), c_error_3
  3490.          RETURN
  3491.       ENDIF
  3492.       IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3493.          m.name = basename(g_screens[m.i,1])
  3494.          DO gencomment WITH "Deactivate Code from screen: "+;
  3495.             m.name
  3496.       ENDIF
  3497.       IF NOT EMPTY(DEACTIVATE) AND deacttype<>0
  3498.          \#REGION <<INT(m.i)>>
  3499.          DO writecode WITH DEACTIVATE, getplatname(m.i), c_fromone, c_untilend, m.i
  3500.       ENDIF
  3501.    ENDFOR
  3502.    m.g_screen = 0
  3503. ENDIF
  3504.  
  3505. *
  3506. * SHOWCLAUSE - Generate Read level Show clause procedure.
  3507. *
  3508. * Description:
  3509. * Generate the function containing the code segment(s) provided
  3510. * by the user for the read level SHOW clause.  The function generated
  3511. * for the show clause will consist of refreshable @...SAY code and
  3512. * code segment(s) if applicable. If multiple reads have been chosen,
  3513. * then this procedure generates a function for a single screen
  3514. * (i.e., the one it has been called for).  If single read has been
  3515. * chosen and there are multiple screens, we will concatenate show
  3516. * clause code segments from all screens to form a single function.
  3517. * Each individual screen's refreshable SAYs will be enclosed in
  3518. * "IF SYS(2016)=('windowname') OR SYS(2016) = '*'" statement.
  3519. * (Desk top will be represented by a null character.)
  3520. *
  3521. *!*****************************************************************************
  3522. *!
  3523. *!      Procedure: SHOWCLAUSE
  3524. *!
  3525. *!      Called by: GENCLAUSECODE      (procedure in GENSCRN.PRG)
  3526. *!
  3527. *!          Calls: GENFUNCHEADER      (procedure in GENSCRN.PRG)
  3528. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3529. *!               : GETPLATNAME()      (function  in GENSCRN.PRG)
  3530. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  3531. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  3532. *!               : BASENAME()         (function  in GENSCRN.PRG)
  3533. *!               : GENCOMMENT         (procedure in GENSCRN.PRG)
  3534. *!
  3535. *!*****************************************************************************
  3536. PROCEDURE showclause
  3537. PARAMETER m.screenno
  3538. PRIVATE m.i, m.comment, m.name, m.thispretext, m.oldshow, m.showmod
  3539.  
  3540. IF m.g_showtype = "EXPR" OR EMPTY(m.g_showtype)
  3541.    RETURN
  3542. ENDIF
  3543. DO genfuncheader WITH m.g_showname, "Read Level Show", .T.
  3544.  
  3545. \FUNCTION <<m.g_showname>>     && Read Level Show
  3546. \PRIVATE currwind
  3547.  
  3548. \STORE WOUTPUT() TO currwind
  3549. m.thispretext = _PRETEXT
  3550. _PRETEXT = ""
  3551.  
  3552. IF m.g_multreads
  3553.    DO seekheader WITH m.screenno
  3554.    m.oldshow = Show
  3555.  
  3556.    m.showmod = ChkShow()
  3557.  
  3558.    m.comment = .T.
  3559.    \#REGION <<INT(m.screenno)>>
  3560.    IF NOT EMPTY(show) AND showtype<>0
  3561.       DO writecode WITH show, getplatname(m.screenno), c_fromone, c_untilend, m.screenno
  3562.    ENDIF
  3563.    DO placesays WITH m.comment, m.g_showname, m.screenno
  3564.    IF m.showmod
  3565.       REPLACE show WITH m.oldshow
  3566.    ENDIF
  3567. ELSE
  3568.    FOR m.i = 1 TO m.g_nscreens
  3569.       m.g_screen = m.i
  3570.       m.dbalias = g_screens[m.i,5]
  3571.       SELECT (m.dbalias)
  3572.       m.comment = .F.
  3573.  
  3574.       DO seekheader WITH m.i
  3575.  
  3576.       m.name = basename(g_screens[m.i,1])
  3577.       IF NOT EMPTY(show) AND showtype<>0
  3578.          m.oldshow = Show   && record show snippet
  3579.          m.showmod = ChkShow()         && may modify show snippet directly
  3580.  
  3581.          DO gencomment WITH "Show Code from screen: "+m.name
  3582.          \#REGION <<INT(m.i)>>
  3583.          m.comment = .T.
  3584.          DO writecode WITH show, getplatname(m.i), c_fromone, c_untilend, m.i
  3585.          IF m.showmod
  3586.             REPLACE show WITH m.oldshow
  3587.          ENDIF
  3588.       ENDIF
  3589.       DO seekheader WITH m.i
  3590.       DO placesays WITH m.comment, m.name, m.i
  3591.    ENDFOR
  3592.    m.g_screen = 0
  3593. ENDIF
  3594. _PRETEXT = m.thispretext
  3595.  
  3596. IF !m.g_noreadplain
  3597.    \IF NOT EMPTY(currwind)
  3598.    \    ACTIVATE WINDOW (currwind) SAME
  3599.    \ENDIF
  3600. ENDIF
  3601.  
  3602. *!*****************************************************************************
  3603. *!
  3604. *!      Function: CHKSHOW
  3605. *!
  3606. *!*****************************************************************************
  3607. FUNCTION chkshow
  3608. PRIVATE m.thelineno, m.theline, m.oldmline, m.upline, m.newshow, m.found_one, m.leadspace, ;
  3609.    m.oldtext, m.theword, m.getsonly, m.j
  3610. * Check for a poisonous SHOW GETS in the SHOW snippet.  If one if executed
  3611. * there, runaway recursion results.
  3612. IF c_checkshow == 0   && check to see if this safety feature is enabled.
  3613.    RETURN .F.
  3614. ENDIF
  3615. m.thelineno = ATCLINE("SHOW GETS",show)
  3616. m.oldmline = _MLINE
  3617. m.oldtext = _TEXT
  3618. m.found_one = .F.
  3619. IF m.thelineno > 0
  3620.    * Step through the SHOW snippet a line at a time, commenting out any SHOW GETS or
  3621.    * SHOW GETS OFF statements.
  3622.    m.newshow = ""
  3623.    _MLINE = 0
  3624.    DO WHILE _MLINE < LEN(show)
  3625.       m.theline = MLINE(show,1,_MLINE)
  3626.       m.upline  = UPPER(LTRIM(m.theline))
  3627.       IF wordnum(m.upline,1) == "SHOW" AND wordnum(m.upline,2) == "GETS" ;
  3628.              AND (EMPTY(wordnum(m.upline,3)) OR wordnum(m.upline,3) == "OFF")
  3629.          m.leadspace = LEN(m.theline) - LEN(m.upline)
  3630.          m.newshow = m.newshow + SPACE(m.leadspace) + ;
  3631.             "* Commented out by GENSCRN: " + LTRIM(m.theline) + CHR(13) + CHR(10)
  3632.          DO errorhandler WITH "SHOW GETS statement commented out of SHOW snippet.",;
  3633.               LINENO(),c_error_1
  3634.          m.found_one = .T.
  3635.       ELSE
  3636.          m.newshow = m.newshow + m.theline + CHR(13) + CHR(10)
  3637.       ENDIF
  3638.    ENDDO
  3639.    IF m.found_one
  3640.       REPLACE show WITH m.newshow
  3641.    ENDIF
  3642. ENDIF
  3643. _MLINE = m.oldmline
  3644. _TEXT  = m.oldtext
  3645. RETURN m.found_one
  3646.  
  3647. *
  3648. * PLACESAYS - Generate @...SAY for refreshable says in the .PRG file.
  3649. *
  3650. * Description:
  3651. * Place @...SAY code for all refreshable say statements into
  3652. * the generated SHOW clause function.
  3653. *
  3654. *!*****************************************************************************
  3655. *!
  3656. *!      Procedure: PLACESAYS
  3657. *!
  3658. *!      Called by: SHOWCLAUSE         (procedure in GENSCRN.PRG)
  3659. *!
  3660. *!          Calls: GENCOMMENT         (procedure in GENSCRN.PRG)
  3661. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  3662. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  3663. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  3664. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  3665. *!               : ANYPICTURE         (procedure in GENSCRN.PRG)
  3666. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  3667. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  3668. *!
  3669. *!*****************************************************************************
  3670. PROCEDURE placesays
  3671. PARAMETER m.comment, m.scrnname, m.g_thisscreen
  3672. PRIVATE m.iswindow, m.sayfound, m.windowname, m.theexpr, m.occur, m.pos
  3673.  
  3674. IF EMPTY(STYLE)
  3675.    m.iswindow = .F.
  3676. ELSE
  3677.    m.iswindow = .T.
  3678.    m.windowname = g_screens[m.g_thisscreen,2]
  3679. ENDIF
  3680. m.sayfound = .T.
  3681. SCAN FOR ((objtype = c_otfield AND objcode = c_sgsay) OR ;
  3682.       (objtype = c_otpicture)) AND ;
  3683.       REFRESH = .T. AND (g_screens[m.g_thisscreen, 6] OR platform = g_screens[m.g_thisscreen, 7])
  3684.    IF m.sayfound
  3685.       IF NOT m.comment
  3686.          DO gencomment WITH "Show Code from screen: "+m.scrnname
  3687.          \#REGION <<INT(m.g_thisscreen)>>
  3688.       ENDIF
  3689.       IF !m.g_noreadplain    && not just emitting plain @ SAYs/GETs
  3690.          \IF SYS(2016) =
  3691.          IF m.iswindow
  3692.             \\ "<<UPPER(m.windowname)>>" OR SYS(2016) = "*"
  3693.             \   ACTIVATE WINDOW <<m.windowname>> SAME
  3694.          ELSE
  3695.             \\ "" OR SYS(2016) = "*"
  3696.             \   ACTIVATE SCREEN
  3697.          ENDIF
  3698.       ENDIF
  3699.       m.sayfound = .F.
  3700.    ENDIF
  3701.  
  3702.    IF objtype = c_otpicture
  3703.       DO genpicture
  3704.    ELSE
  3705.       m.theexpr = expr
  3706.       IF g_screens[m.g_thisscreen, 7] = 'WINDOWS' OR g_screens[m.g_thisscreen, 7] = 'MAC'
  3707.          SET DECIMALS TO 3
  3708.          m.occur = 1
  3709.          m.pos = AT(CHR(13), m.theexpr, m.occur)
  3710.  
  3711.          * Sometimes the screen builder surrounds text with single quotes and other
  3712.          * times with double quotes.
  3713.          q1 = LEFT(LTRIM(m.theexpr),1)
  3714.  
  3715.          DO WHILE m.pos > 0
  3716.             IF q1 = "'"
  3717.                m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  3718.                   "' + CHR(13) + ;" + CHR(13)  + CHR(9) + CHR(9) + "'" ;
  3719.                   + SUBSTR(m.theexpr, m.pos + 1)
  3720.             ELSE
  3721.                m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  3722.                   '" + CHR(13) + ;' + CHR(13)  + CHR(9) + CHR(9) + '"' ;
  3723.                   + SUBSTR(m.theexpr, m.pos + 1)
  3724.             ENDIF
  3725.             m.occur = m.occur + 1
  3726.             m.pos = AT(CHR(13), m.theexpr, m.occur)
  3727.          ENDDO
  3728.          IF mode = 1 AND objtype = c_otfield  AND objcode = c_sgsay    && transparent SAY text
  3729.             * Clear the space that the SAY is going into.  This makes refreshable SAYS
  3730.             * work with transparent fonts.
  3731.             \   @ <<Vpos>>,<<Hpos>> CLEAR TO <<Vpos+Height>>,<<Hpos+Width>>
  3732.          ENDIF
  3733.       ENDIF
  3734.       \ @ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  3735.       \         SIZE <<Height>>,<<Width>>, <<Spacing>>
  3736.       SET DECIMALS TO 0
  3737.       DO pushindent
  3738.       DO anyfont
  3739.       DO anystyle
  3740.       DO anypicture
  3741.       DO anyscheme
  3742.       DO popindent
  3743.    ENDIF
  3744. ENDSCAN
  3745. IF NOT m.sayfound
  3746.    \ENDIF
  3747. ENDIF
  3748.  
  3749. *
  3750. * GENCLOSEDBFS - Generate code to close all previously opened databases.
  3751. *
  3752. *!*****************************************************************************
  3753. *!
  3754. *!      Procedure: GENCLOSEDBFS
  3755. *!
  3756. *!      Called by: GENCLNENVIRON      (procedure in GENSCRN.PRG)
  3757. *!
  3758. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  3759. *!               : UNIQUEDBF()        (function  in GENSCRN.PRG)
  3760. *!
  3761. *!*****************************************************************************
  3762. PROCEDURE genclosedbfs
  3763. PRIVATE m.i, m.dbalias, m.dbfcnt, m.firstfound
  3764. m.firstfound = .T.
  3765. m.dbfcnt = 0
  3766. g_dbfs = ""
  3767. FOR m.i = 1 TO m.g_nscreens
  3768.    m.g_screen = m.i
  3769.    m.dbalias = g_screens[m.i,5]
  3770.    SELECT (m.dbalias)
  3771.    SCAN FOR objtype = c_otworkarea AND (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  3772.       IF m.firstfound
  3773.          DO commentblock WITH ""," Closing Databases"
  3774.          m.firstfound = .F.
  3775.       ENDIF
  3776.       IF uniquedbf(TAG)
  3777.          m.dbfcnt = m.dbfcnt + 1
  3778.          DIMENSION g_dbfs[m.dbfcnt]
  3779.          g_dbfs[m.dbfcnt] = TAG
  3780.       ELSE
  3781.          LOOP
  3782.       ENDIF
  3783.       \IF USED("<<LOWER(stripext(strippath(Tag)))>>")
  3784.       \ SELECT <<LOWER(stripext(strippath(Tag)))>>
  3785.       \ USE
  3786.       \ENDIF
  3787.       \
  3788.    ENDSCAN
  3789. ENDFOR
  3790. m.g_screen = 0
  3791. IF m.g_closefiles
  3792.    \SELECT (m.currarea)
  3793.    \
  3794. ENDIF
  3795. DIMENSION g_dbfs[1]
  3796.  
  3797. *
  3798. * GENOPENDBFS - Generate USE... statement(s).
  3799. *
  3800. * Description:
  3801. * Generate code to open databases, set indexes, and relations as
  3802. * specified by the user.
  3803. *
  3804. *!*****************************************************************************
  3805. *!
  3806. *!      Procedure: GENOPENDBFS
  3807. *!
  3808. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  3809. *!
  3810. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  3811. *!               : UNIQUEDBF()        (function  in GENSCRN.PRG)
  3812. *!               : GENUSESTMTS        (procedure in GENSCRN.PRG)
  3813. *!               : STRIPPATH()        (function  in GENSCRN.PRG)
  3814. *!               : ERRORHANDLER       (procedure in GENSCRN.PRG)
  3815. *!               : GENRELATIONS       (procedure in GENSCRN.PRG)
  3816. *!
  3817. *!*****************************************************************************
  3818. PROCEDURE genopendbfs
  3819. PRIVATE m.dbalias, m.i, m.dbfcnt, m.string, m.msg, m.firstfound
  3820. m.firstfound = .T.
  3821. FOR m.i = 1 TO m.g_nscreens
  3822.    m.g_screen = m.i
  3823.    m.dbalias = g_screens[m.i,5]
  3824.    SELECT (m.dbalias)
  3825.    m.dbfcnt = 0
  3826.    SCAN FOR objtype = c_otworkarea AND (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  3827.       IF m.firstfound
  3828.          DO commentblock WITH m.dbalias, ;
  3829.             " Databases, Indexes, Relations"
  3830.          m.firstfound = .F.
  3831.       ENDIF
  3832.       IF uniquedbf(TAG)
  3833.          m.dbfcnt = m.dbfcnt + 1
  3834.          DIMENSION g_dbfs[m.dbfcnt]
  3835.          g_dbfs[m.dbfcnt] = TAG
  3836.       ELSE
  3837.          LOOP
  3838.       ENDIF
  3839.       DO genusestmts WITH m.i
  3840.    ENDSCAN
  3841.  
  3842.    IF m.dbfcnt > 1
  3843.       IF NOT EMPTY(m.g_current)
  3844.          \SELECT <<m.g_current>>
  3845.       ELSE
  3846.          m.msg = "Please RE-SAVE screen environment... SCREEN: "+;
  3847.             strippath(g_screens[m.i,1])
  3848.          DO errorhandler WITH m.msg, LINENO(), c_error_1
  3849.       ENDIF
  3850.       \
  3851.    ENDIF
  3852. ENDFOR
  3853. m.g_screen = 0
  3854. DO genrelations
  3855.  
  3856. *
  3857. * UNIQUEDBF - Check if database name already seen.
  3858. *
  3859. *!*****************************************************************************
  3860. *!
  3861. *!       Function: UNIQUEDBF
  3862. *!
  3863. *!      Called by: GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  3864. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  3865. *!
  3866. *!*****************************************************************************
  3867. FUNCTION uniquedbf
  3868. PARAMETER m.dbfname
  3869. RETURN IIF(ASCAN(g_dbfs, m.dbfname)=0,.T.,.F.)
  3870.  
  3871. *
  3872. * GENUSESTMTS - Generate USE... statements
  3873. *
  3874. * Description:
  3875. * Generate USE... statements for each database encoded in the
  3876. * screen database.  Generate ORDER statement if appropriate.
  3877. *
  3878. *!*****************************************************************************
  3879. *!
  3880. *!      Procedure: GENUSESTMTS
  3881. *!
  3882. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  3883. *!
  3884. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  3885. *!               : GENORDER           (procedure in GENSCRN.PRG)
  3886. *!               : GENINDEXES()       (function  in GENSCRN.PRG)
  3887. *!
  3888. *!*****************************************************************************
  3889. PROCEDURE genusestmts
  3890. PARAMETER m.i
  3891. PRIVATE m.workarea, saverecno, MARGIN, m.name, m.order, m.tag
  3892. m.workarea  = objcode
  3893. saverecno = RECNO()
  3894. m.order   = LOWER(ALLTRIM(ORDER))
  3895. m.tag     = LOWER(ALLTRIM(tag2))
  3896. m.name    = LOWER(TAG)
  3897. m.relpath = LOWER(findrelpath(name))
  3898.  
  3899. IF UNIQUE AND EMPTY(m.g_current)
  3900.    m.g_current = m.name
  3901. ENDIF
  3902.  
  3903. MARGIN = 4
  3904. IF EMPTY(name)
  3905.    \SELECT <<m.name>>
  3906.    RETURN
  3907. ENDIF
  3908. \IF USED("<<m.name>>")
  3909. \       SELECT <<m.name>>
  3910. IF genindexes ("select", m.i)=0
  3911.    indexfound = 0
  3912.    \    SET ORDER TO
  3913.    DO genorder WITH indexfound,m.order,m.tag,m.name
  3914. ELSE
  3915.    indexfound = 1
  3916.    \\ ADDITIVE ;
  3917.    \            ORDER
  3918.    DO genorder WITH indexfound,m.order,m.tag,m.name
  3919. ENDIF
  3920.  
  3921. \ELSE
  3922. \       SELECT 0
  3923. \       USE (LOCFILE("<<m.relpath>>","DBF",
  3924. \\"Where is <<basename(m.relpath)>>?"));
  3925. \               AGAIN ALIAS <<m.name>>
  3926. MARGIN = 42+LEN(m.relpath)+2*LEN(m.name)
  3927. = genindexes("use", m.i)
  3928.  
  3929. GOTO saverecno
  3930. \\ ;
  3931. \               ORDER
  3932. DO genorder WITH indexfound,m.order,m.tag,m.name
  3933. \ENDIF
  3934. \
  3935.  
  3936. *
  3937. * FINDRELPATH - Find relative path for DATABASES.
  3938. *
  3939. *!*****************************************************************************
  3940. *!
  3941. *!       Function: FINDRELPATH
  3942. *!
  3943. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  3944. *!               : GENINDEXES()       (function  in GENSCRN.PRG)
  3945. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  3946. *!               : ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  3947. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  3948. *!               : ANYICON            (procedure in GENSCRN.PRG)
  3949. *!
  3950. *!*****************************************************************************
  3951. FUNCTION findrelpath
  3952. PARAMETER m.name
  3953. PRIVATE m.fullpath, m.relpath
  3954. m.fullpath = FULLPATH(m.name, g_screens[1,1])
  3955. m.relpath  = SYS(2014, m.fullpath, m.g_homedir)
  3956. RETURN m.relpath
  3957.  
  3958. *
  3959. * GENORDER - Generate ORDER clause.
  3960. *
  3961. *!*****************************************************************************
  3962. *!
  3963. *!      Procedure: GENORDER
  3964. *!
  3965. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  3966. *!
  3967. *!*****************************************************************************
  3968. PROCEDURE genorder
  3969. PARAMETER m.indexfound, m.order, m.tag, m.dbfname
  3970. IF EMPTY(m.order) AND EMPTY(m.tag)
  3971.    \\ 0
  3972.    RETURN
  3973. ENDIF
  3974. IF m.indexfound=0
  3975.    \\ TAG "<<m.tag>>"
  3976. ELSE
  3977.    IF EMPTY(m.tag)
  3978.       \\ <<basename(m.order)>>
  3979.    ELSE
  3980.       \\ TAG "<<m.tag>>"
  3981.       IF NOT EMPTY (m.order)
  3982.          \\ OF <<m.order>>
  3983.       ENDIF
  3984.    ENDIF
  3985. ENDIF
  3986.  
  3987. *
  3988. * GENINDEXES - Generate index names for a USE statement.
  3989. *
  3990. *!*****************************************************************************
  3991. *!
  3992. *!       Function: GENINDEXES
  3993. *!
  3994. *!      Called by: GENUSESTMTS        (procedure in GENSCRN.PRG)
  3995. *!
  3996. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  3997. *!
  3998. *!*****************************************************************************
  3999. FUNCTION genindexes
  4000. PARAMETER m.placement, m.i
  4001. PRIVATE m.idxcount, m.relpath
  4002. m.idxcount = 0
  4003.  
  4004. SCAN FOR objtype = c_otindex AND objcode = WORKAREA AND;
  4005.       (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4006.    m.relpath = LOWER(findrelpath(name))
  4007.    IF m.idxcount > 0
  4008.       IF MARGIN > 55
  4009.          MARGIN = 8 + LEN(m.relpath)
  4010.          \\, ;
  4011.          \              <<m.relpath>>
  4012.       ELSE
  4013.          \\, <<m.relpath>>
  4014.          MARGIN = MARGIN + 2 + LEN(m.relpath)
  4015.       ENDIF
  4016.    ELSE
  4017.       IF m.placement = "use"
  4018.          \\ ;
  4019.          \              INDEX <<m.relpath>>
  4020.          MARGIN = 8 + LEN(m.relpath)
  4021.       ELSE
  4022.          \      SET INDEX TO <<m.relpath>>
  4023.          MARGIN = 17
  4024.          MARGIN = MARGIN + LEN(m.relpath)
  4025.       ENDIF
  4026.    ENDIF
  4027.    m.idxcount = m.idxcount + 1
  4028. ENDSCAN
  4029. RETURN m.idxcount
  4030.  
  4031. *
  4032. * GENRELATIONS - Generate code to set all existing relations as they
  4033. *                                are encoded in the screen file(s).
  4034. *
  4035. * Description:
  4036. * Generate code for all relations as encoded in the screen database.
  4037. *
  4038. *!*****************************************************************************
  4039. *!
  4040. *!      Procedure: GENRELATIONS
  4041. *!
  4042. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  4043. *!
  4044. *!          Calls: SEEKHEADER         (procedure in GENSCRN.PRG)
  4045. *!               : GENRELSTMTS        (procedure in GENSCRN.PRG)
  4046. *!
  4047. *!*****************************************************************************
  4048. PROCEDURE genrelations
  4049. PRIVATE m.dbalias, m.i
  4050. FOR m.i = 1 TO m.g_nscreens
  4051.    m.g_screen = m.i
  4052.    m.dbalias  = g_screens[m.i,5]
  4053.    SELECT (m.dbalias)
  4054.  
  4055.    DO seekheader WITH m.i
  4056.    DO genrelstmts WITH m.i
  4057. ENDFOR
  4058. m.g_screen = 0
  4059.  
  4060. *
  4061. * GENRELSTMTS - Generate relation statements.
  4062. *
  4063. *!*****************************************************************************
  4064. *!
  4065. *!      Procedure: GENRELSTMTS
  4066. *!
  4067. *!      Called by: GENRELATIONS       (procedure in GENSCRN.PRG)
  4068. *!
  4069. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  4070. *!
  4071. *!*****************************************************************************
  4072. PROCEDURE genrelstmts
  4073. PARAMETER m.i
  4074. PRIVATE m.saverec, m.last, m.firstrel, m.firstsel, m.dbalias, m.setskip
  4075. m.dbalias  = ""
  4076. m.firstrel = .T.
  4077. m.firstsel = .T.
  4078. m.last     = 0
  4079. m.setskip  = ""
  4080.  
  4081. SCAN FOR objtype = c_otrel AND ;
  4082.       (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4083.    IF m.last<> objcode
  4084.       IF NOT (m.firstrel OR EMPTY(m.setskip))
  4085.          \SET SKIP TO <<m.setskip>>
  4086.          \
  4087.       ENDIF
  4088.       m.saverec = RECNO()
  4089.       m.last= objcode
  4090.  
  4091.       SCAN FOR objtype = c_otworkarea AND objcode = m.last AND ;
  4092.             (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4093.          m.dbalias = LOWER(basename(TAG))
  4094.          IF NOT (m.firstrel AND m.g_current = m.dbalias)
  4095.             \SELECT <<m.dbalias>>
  4096.          ENDIF
  4097.          m.setskip = ALLTRIM(LOWER(expr))
  4098.       ENDSCAN
  4099.  
  4100.       GOTO RECORD m.saverec
  4101.       m.firstrel = .F.
  4102.    ENDIF
  4103.  
  4104.    IF !(m.firstsel AND LOWER(tag2) == LOWER(m.g_current))
  4105.       \SELECT <<LOWER(Tag2)>>
  4106.       \
  4107.    ENDIF
  4108.    \SET RELATION OFF INTO <<LOWER(Tag)>>
  4109.    \SET RELATION TO <<LOWER(Expr)>> INTO <<LOWER(Tag)>> ADDITIVE
  4110.    \
  4111.  
  4112.    m.firstsel = .F.
  4113. ENDSCAN
  4114.  
  4115. IF m.last<> 0
  4116.    IF NOT EMPTY(m.setskip))
  4117.       \SET SKIP TO <<m.setskip>>
  4118.       \
  4119.    ENDIF
  4120.    IF NOT EMPTY(m.g_current)
  4121.       \SELECT <<m.g_current>>
  4122.    ENDIF
  4123. ENDIF
  4124.  
  4125. **
  4126. ** Code Associated With Building of the Format file statements.
  4127. **
  4128.  
  4129. *
  4130. * BUILDFMT - Build Format file statements.
  4131. *
  4132. * Description:
  4133. * Generate all boxes, text, fields, push buttons, radio buttons,
  4134. * popups, check boxes and scrollable lists encoded in a screen set.
  4135. *
  4136. *!*****************************************************************************
  4137. *!
  4138. *!      Procedure: BUILDFMT
  4139. *!
  4140. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  4141. *!
  4142. *!          Calls: MULTIPLAT()        (function  in GENSCRN.PRG)
  4143. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  4144. *!               : PUTMSG             (procedure in GENSCRN.PRG)
  4145. *!               : SEEKHEADER         (procedure in GENSCRN.PRG)
  4146. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  4147. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4148. *!               : UPDTHERM           (procedure in GENSCRN.PRG)
  4149. *!               : ANYWINDOWS         (procedure in GENSCRN.PRG)
  4150. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  4151. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  4152. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  4153. *!               : GENLINES           (procedure in GENSCRN.PRG)
  4154. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  4155. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  4156. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  4157. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  4158. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  4159. *!               : GENLIST            (procedure in GENSCRN.PRG)
  4160. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  4161. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  4162. *!               : GENACTISTMTS       (procedure in GENSCRN.PRG)
  4163. *!               : PLACEREAD          (procedure in GENSCRN.PRG)
  4164. *!
  4165. *!*****************************************************************************
  4166. PROCEDURE buildfmt
  4167. PARAMETER pnum   && platform number
  4168. PRIVATE m.pos, m.dbalias, m.adjuster, m.recadjust, m.factor, m.i, m.sn
  4169. m.msg = 'Generating Screen Code'
  4170. IF multiplat()
  4171.    m.msg = m.msg + " for "+versioncap(m.g_genvers)
  4172. ENDIF
  4173. DO putmsg WITH m.msg
  4174. m.g_nwindows = 0
  4175. m.adjuster   = INT(25/m.g_nscreens)
  4176. m.recadjust  = 35
  4177. FOR m.sn = 1 TO m.g_nscreens
  4178.    m.g_screen = m.sn
  4179.    m.dbalias = g_screens[m.sn,5]
  4180.    SELECT (m.dbalias)
  4181.    DO seekheader WITH m.sn
  4182.    m.factor = m.adjuster/RECCOUNT()
  4183.    DO commentblock WITH g_screens[m.sn,1], " Screen Layout"
  4184.    \#REGION <<INT(m.sn)>>
  4185.    IF ATC('#ITSE',setupcode)<>0
  4186.       DO gendirective WITH ;
  4187.          MLINE(setupcode,ATCLINE('#ITSE',setupcode)),;
  4188.          '#ITSE'
  4189.    ENDIF
  4190.    SCAN FOR (g_screens[m.sn, 6] OR platform = g_screens[m.sn, 7])
  4191.       m.recadjust = m.recadjust + m.factor
  4192.       DO updtherm WITH INT(m.recadjust) * m.pnum
  4193.  
  4194.       DO CASE
  4195.       CASE objtype = c_otscreen
  4196.          DO anywindows WITH (m.sn)
  4197.       CASE objtype = c_ottext
  4198.          DO gentext
  4199.       CASE objtype = c_otfield
  4200.          DO genfields
  4201.       CASE objtype = c_otbox
  4202.          DO genboxes
  4203.       CASE objtype = c_otline
  4204.          DO genlines
  4205.       CASE objtype = c_ottxtbut
  4206.          DO genpush
  4207.       CASE objtype = c_otradbut
  4208.          DO genradbut
  4209.       CASE objtype = c_otinvbut
  4210.          DO geninvbut
  4211.       CASE objtype = c_otpopup
  4212.          DO genpopup
  4213.       CASE objtype = c_otchkbox
  4214.          DO genchkbox
  4215.       CASE objtype = c_otlist
  4216.          DO genlist
  4217.       CASE objtype = c_otpicture
  4218.          DO genpicture
  4219.       CASE objtype = c_otspinner
  4220.          DO genspinner
  4221.       ENDCASE
  4222.    ENDSCAN
  4223.    DO genactistmts WITH (m.sn)
  4224.    IF !m.g_noread
  4225.       DO placeread WITH (m.sn)
  4226.    ENDIF
  4227. ENDFOR
  4228. m.g_screen = 0
  4229.  
  4230. *
  4231. * ANYWINDOWS - Issue ACTIVATE WINDOW ... SAME.
  4232. *
  4233. * Description:
  4234. * If windows present issue ACTIVATE WINDOW...SAME to make sure
  4235. * that the windows stack on screen in the correct order.
  4236. *
  4237. *!*****************************************************************************
  4238. *!
  4239. *!      Procedure: ANYWINDOWS
  4240. *!
  4241. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4242. *!
  4243. *!          Calls: GENACTWINDOW       (procedure in GENSCRN.PRG)
  4244. *!
  4245. *!*****************************************************************************
  4246. PROCEDURE anywindows
  4247. PARAMETER m.scrnno
  4248. PRIVATE m.pos
  4249. IF m.g_noreadplain
  4250.    RETURN
  4251. ENDIF
  4252.  
  4253. IF NOT EMPTY(STYLE)
  4254.    DO genactwindow WITH m.scrnno
  4255.  
  4256.    m.g_lastwindow = g_screens[m.scrnno,2]
  4257.    m.pos = ASCAN(g_wndows, m.g_lastwindow)
  4258.    * m.pos contains the element number (not the row) that matches.
  4259.    * The element number + 1 is a number representing window sequence.
  4260.    IF EMPTY(g_wndows[m.pos+1])
  4261.       m.g_nwindows = m.g_nwindows + 1
  4262.       g_wndows[m.pos+1] = m.g_nwindows
  4263.    ENDIF
  4264.  
  4265.    m.g_defasch1 = SCHEME
  4266.    m.g_defasch2 = scheme2
  4267. ELSE
  4268.    m.g_defasch1 = 0
  4269.    m.g_defasch2 = 0
  4270.  
  4271.    IF m.g_lastwindow<>""
  4272.       \HIDE WINDOW ALL
  4273.       \ACTIVATE SCREEN
  4274.       m.g_lastwindow = ""
  4275.    ENDIF
  4276. ENDIF
  4277.  
  4278. *
  4279. * GENACTISTMTS - Generate Activate window statements.
  4280. *
  4281. * Description:
  4282. * Generate ACTIVATE WINDOW... statements in order to activate all
  4283. * windows which have been previously activated with SAME clause.
  4284. *
  4285. *!*****************************************************************************
  4286. *!
  4287. *!      Procedure: GENACTISTMTS
  4288. *!
  4289. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4290. *!
  4291. *!*****************************************************************************
  4292. PROCEDURE genactistmts
  4293. PARAMETER m.scrnno
  4294. PRIVATE m.j, m.pos
  4295. \
  4296. IF m.scrnno=m.g_nscreens AND NOT m.g_multreads AND NOT m.g_noreadplain
  4297.    IF m.g_nwindows = 1
  4298.       \IF NOT WVISIBLE("<<g_wndows[1,1]>>")
  4299.       \ ACTIVATE WINDOW <<g_wndows[1,1]>>
  4300.       \ENDIF
  4301.       RETURN
  4302.    ENDIF
  4303.    FOR m.j = m.g_nwindows TO 1 STEP -1
  4304.       m.pos = ASCAN(g_wndows, m.j)
  4305.       * pos contains the element *numbered* j.  This will be somewhere in g_wndows[*,2].
  4306.       * Look to the preceding element to get the window name.
  4307.       IF m.pos<>0
  4308.          \IF NOT WVISIBLE("<<g_wndows[m.pos-1]>>")
  4309.          \      ACTIVATE WINDOW <<g_wndows[m.pos-1]>>
  4310.          \ENDIF
  4311.       ENDIF
  4312.    ENDFOR
  4313.    \
  4314. ENDIF
  4315.  
  4316. *
  4317. * PLACEREAD - Generate a 'READ' statement.
  4318. *
  4319. * Description:
  4320. * Called once per screen in the screen set.
  4321. * Generate a READ statement.  Depending on whether this is a single
  4322. * or multiread the read statement may be generated between @...SAY/GETs
  4323. * from each screen or at the end of a set of all @...SAY/GETs.
  4324. *
  4325. *!*****************************************************************************
  4326. *!
  4327. *!      Procedure: PLACEREAD
  4328. *!
  4329. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4330. *!
  4331. *!          Calls: ANYMODAL           (procedure in GENSCRN.PRG)
  4332. *!               : ANYLOCK            (procedure in GENSCRN.PRG)
  4333. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4334. *!               : GENWITHCLAUSE      (procedure in GENSCRN.PRG)
  4335. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  4336. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  4337. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4338. *!               : GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4339. *!               : GENCLAUSECODE      (procedure in GENSCRN.PRG)
  4340. *!
  4341. *!*****************************************************************************
  4342. PROCEDURE placeread
  4343. PARAMETER m.scrnno
  4344. PRIVATE thispretext
  4345.  
  4346. \
  4347. IF m.g_multreads
  4348.    DO newreadclauses
  4349.    \READ
  4350.    IF m.g_readcycle AND m.scrnno = m.g_nscreens
  4351.       \\ CYCLE
  4352.    ENDIF
  4353.    DO anymodal
  4354.    DO anylock
  4355.    DO doplaceclause WITH m.scrnno
  4356.    DO genwithclause
  4357.    DO gengivenread WITH m.scrnno
  4358. ELSE
  4359.    IF NOT EMPTY(m.g_rddir) AND m.scrnno = m.g_nscreens
  4360.       DO commentblock WITH "","READ contains clauses from SCREEN "+;
  4361.          LOWER(g_screens[m.g_rddirno,5])
  4362.    ENDIF
  4363.    DO findreadclauses WITH m.scrnno
  4364.    IF m.scrnno = m.g_nscreens
  4365.       \READ
  4366.       IF m.g_readcycle
  4367.          \\ CYCLE
  4368.       ENDIF
  4369.       DO anymodal
  4370.       DO anylock
  4371.       DO genreadclauses
  4372.       DO genwithclause
  4373.       DO gengivenread WITH m.scrnno
  4374.       _TEXT = m.g_tmphandle
  4375.       m.thispretext = _PRETEXT
  4376.       _PRETEXT = ""
  4377.       DO genclausecode WITH m.scrnno
  4378.       _TEXT = m.g_orghandle
  4379.       _PRETEXT = m.thispretext
  4380.    ENDIF
  4381. ENDIF
  4382. \
  4383.  
  4384. *
  4385. * ANYMODAL - Generate MODAL clause on READ.
  4386. *
  4387. *!*****************************************************************************
  4388. *!
  4389. *!      Procedure: ANYMODAL
  4390. *!
  4391. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4392. *!
  4393. *!*****************************************************************************
  4394. PROCEDURE anymodal
  4395. IF m.g_readmodal
  4396.    \\ MODAL
  4397. ENDIF
  4398.  
  4399. *
  4400. * ANYLOCK - Generate LOCK/NOLOCK clause on READ.
  4401. *
  4402. *!*****************************************************************************
  4403. *!
  4404. *!      Procedure: ANYLOCK
  4405. *!
  4406. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4407. *!
  4408. *!*****************************************************************************
  4409. PROCEDURE anylock
  4410. IF m.g_readlock
  4411.    \\ NOLOCK
  4412. ENDIF
  4413.  
  4414. *
  4415. * GENWITHCLAUSE - Generate WITH clause on a READ.
  4416. *
  4417. *!*****************************************************************************
  4418. *!
  4419. *!      Procedure: GENWITHCLAUSE
  4420. *!
  4421. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4422. *!
  4423. *!*****************************************************************************
  4424. PROCEDURE genwithclause
  4425. IF NOT EMPTY(m.g_withlist)
  4426.    \\ ;
  4427.    \    WITH <<m.g_withlist>>
  4428. ENDIF
  4429.  
  4430. *
  4431. * DOPLACECLAUSE - Place READ level clauses for multiple reads.
  4432. *
  4433. * Description:
  4434. * According to the read level clauses encoded in the screen file
  4435. * set variables holding information about each clause.
  4436. *
  4437. *!*****************************************************************************
  4438. *!
  4439. *!      Procedure: DOPLACECLAUSE
  4440. *!
  4441. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4442. *!
  4443. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  4444. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4445. *!               : GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4446. *!               : GENCLAUSECODE      (procedure in GENSCRN.PRG)
  4447. *!
  4448. *!*****************************************************************************
  4449. PROCEDURE doplaceclause
  4450. PARAMETER m.scrnno
  4451. PRIVATE thispretext
  4452. IF g_screens[m.scrnno, 6]
  4453.    LOCATE FOR objtype = c_otscreen
  4454. ELSE
  4455.    LOCATE FOR platform = g_screens[m.scrnno, 7] AND objtype = c_otscreen
  4456. ENDIF
  4457. IF NOT FOUND()
  4458.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  4459.       LINENO(), c_error_3
  4460.    RETURN
  4461. ENDIF
  4462.  
  4463. DO findreadclauses WITH m.scrnno
  4464. DO genreadclauses
  4465. _TEXT = m.g_tmphandle
  4466. m.thispretext = _PRETEXT
  4467. _PRETEXT = ""
  4468.  
  4469. DO genclausecode WITH m.scrnno
  4470. _TEXT = m.g_orghandle
  4471. _PRETEXT = m.thispretext
  4472.  
  4473. *
  4474. * FINDREADCLAUSES - Find clauses for the final READ statement.
  4475. *
  4476. * Description:
  4477. * Keep track of clauses that were already seen to determine what
  4478. * clauses are placed on final read.  If this procedure is called for
  4479. * a multiple read setting, flag's settings apply only to the current
  4480. * screen.
  4481. *
  4482. *!*****************************************************************************
  4483. *!
  4484. *!      Procedure: FINDREADCLAUSES
  4485. *!
  4486. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4487. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4488. *!
  4489. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  4490. *!               : SETCLAUSEFLAGS     (procedure in GENSCRN.PRG)
  4491. *!               : ORCLAUSEFLAGS      (procedure in GENSCRN.PRG)
  4492. *!
  4493. *!*****************************************************************************
  4494. PROCEDURE findreadclauses
  4495. PARAMETER m.scrnno
  4496. PRIVATE m.dbalias, m.cur_rec
  4497. IF g_screens[m.scrnno,6]
  4498.    LOCATE FOR objtype = c_otscreen
  4499. ELSE
  4500.    LOCATE FOR platform = g_screens[m.scrnno, 7] AND objtype = c_otscreen
  4501. ENDIF
  4502. IF NOT FOUND()
  4503.    DO errorhandler WITH "Error in SCX: Objtype=1 not found",;
  4504.       LINENO(), c_error_3
  4505.    RETURN
  4506. ENDIF
  4507.  
  4508. IF EMPTY(m.g_validtype) AND !EMPTY(VALID)
  4509.    DO setclauseflags WITH validtype, VALID, m.g_validname,;
  4510.       m.g_validtype
  4511. ENDIF
  4512. IF EMPTY(m.g_whentype) AND !EMPTY(WHEN)
  4513.    DO setclauseflags  WITH whentype, WHEN, m.g_whenname,;
  4514.       m.g_whentype
  4515. ENDIF
  4516. IF EMPTY(m.g_actitype) AND !EMPTY(ACTIVATE)
  4517.    DO setclauseflags WITH activtype, ACTIVATE, m.g_actiname,;
  4518.       m.g_actitype
  4519. ENDIF
  4520. IF EMPTY(m.g_deattype) AND !EMPTY(DEACTIVATE)
  4521.    DO setclauseflags WITH deacttype, DEACTIVATE, m.g_deatname,;
  4522.       m.g_deattype
  4523. ENDIF
  4524.  
  4525. * SHOW is a special case since it can be generated with both procedures (for refreshable
  4526. * SAYs or just regular procedures) and expressions.  OR the flags together.
  4527. IF !EMPTY(SHOW)
  4528.    IF showtype != c_genexpr
  4529.       DO orclauseflags WITH showtype, SHOW, m.g_showname, m.g_showtype
  4530.    ELSE
  4531.       m.cur_rec = RECNO()
  4532.       * It's an expression, but look for refreshable SAYs too.
  4533.       LOCATE FOR ((objtype = c_otfield AND objcode = c_sgsay) OR (objtype = c_otpicture)) AND ;
  4534.          REFRESH = .T. AND (g_screens[m.scrnno, 6] OR platform = g_screens[m.scrnno, 7])
  4535.       IF FOUND()
  4536.          GOTO m.cur_rec
  4537.          DO orclauseflags WITH c_genboth, SHOW,   m.g_showname, m.g_showtype
  4538.       ELSE
  4539.          GOTO m.cur_rec
  4540.          DO orclauseflags WITH c_genexpr, SHOW,   m.g_showname, m.g_showtype
  4541.       ENDIF
  4542.       m.g_showexpr = m.g_showname
  4543.    ENDIF
  4544. ELSE
  4545.    * Look for refreshable SAYS
  4546.    LOCATE FOR ((objtype = c_otfield AND objcode = c_sgsay) OR (objtype = c_otpicture)) AND ;
  4547.       REFRESH = .T. AND (g_screens[m.scrnno, 6] OR platform = g_screens[m.scrnno, 7])
  4548.    IF FOUND()
  4549.       DO orclauseflags WITH c_gencode, SHOW,   m.g_showname, m.g_showtype
  4550.    ENDIF
  4551. ENDIF
  4552.  
  4553. *
  4554. * SETCLAUSEFLAGS - Load global flags with information about clauses.
  4555. *
  4556. * Description:
  4557. * If a clause is a snippet then a generic name is provided for the
  4558. * clause call statement in the READ and that same name is used to
  4559. * construct the corresponding function.
  4560. *
  4561. * The BOTH setting is used for SHOW clauses that are defined as expressions,
  4562. * in screens that also contain refreshable SAYS.  We have to generate a
  4563. * procedure to contain the code to refresh the SAYS.
  4564. *
  4565. *!*****************************************************************************
  4566. *!
  4567. *!      Procedure: SETCLAUSEFLAGS
  4568. *!
  4569. *!      Called by: FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4570. *!
  4571. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  4572. *!
  4573. *!*****************************************************************************
  4574. PROCEDURE setclauseflags
  4575. PARAMETER m.flagtype, m.memo, m.name, m.type
  4576. DO CASE
  4577. CASE m.flagtype = c_genexpr
  4578.    m.name = m.memo
  4579.    m.type = "EXPR"
  4580. CASE m.flagtype = c_genboth
  4581.    m.name = m.memo
  4582.    m.type = "BOTH"
  4583. OTHERWISE
  4584.    m.name = getcname(m.memo)
  4585.    m.type = "CODE"
  4586. ENDCASE
  4587.  
  4588. *
  4589. * ORCLAUSEFLAGS - Logical OR two flagtypes
  4590. *
  4591. *!*****************************************************************************
  4592. *!
  4593. *!      Procedure: ORCLAUSEFLAGS
  4594. *!
  4595. *!      Called by: FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  4596. *!
  4597. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  4598. *!
  4599. *!*****************************************************************************
  4600. PROCEDURE orclauseflags
  4601. PARAMETER m.flagtype, m.memo, m.name, m.type
  4602. DO CASE
  4603. CASE m.flagtype = c_genexpr
  4604.    m.name = m.memo
  4605.    IF INLIST(m.type,"BOTH","CODE")
  4606.       m.type = "BOTH"
  4607.    ELSE
  4608.       m.type = "EXPR"
  4609.    ENDIF
  4610. CASE m.flagtype = c_genboth
  4611.    m.name = m.memo
  4612.    m.type = "BOTH"
  4613. OTHERWISE
  4614.    * Code of some sort.  The expr code is different for expanded snippets, closed snippets, etc.
  4615.    * It is 2 for expanded snippets and 3 for minimized snippets, for example.
  4616.    m.name = getcname(m.memo)
  4617.    IF INLIST(m.type,"BOTH","EXPR")
  4618.       m.type = "BOTH"
  4619.    ELSE
  4620.       m.type = "CODE"
  4621.    ENDIF
  4622. ENDCASE
  4623.  
  4624. *
  4625. * GENREADCLAUSES - Generate Clauses on a READ.
  4626. *
  4627. * Description:
  4628. * Check if clause is appropriate, if so call GENCLAUSE to
  4629. * generate the clause keyword.
  4630. *
  4631. *!*****************************************************************************
  4632. *!
  4633. *!      Procedure: GENREADCLAUSES
  4634. *!
  4635. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4636. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  4637. *!
  4638. *!          Calls: GENCLAUSE          (procedure in GENSCRN.PRG)
  4639. *!
  4640. *!*****************************************************************************
  4641. PROCEDURE genreadclauses
  4642. IF NOT EMPTY(m.g_validtype)
  4643.    DO genclause WITH "VALID", m.g_validname, m.g_validtype
  4644. ENDIF
  4645. IF NOT EMPTY(m.g_whentype)
  4646.    DO genclause WITH "WHEN", m.g_whenname, m.g_whentype
  4647. ENDIF
  4648. IF NOT EMPTY(m.g_actitype)
  4649.    DO genclause WITH "ACTIVATE", m.g_actiname, m.g_actitype
  4650. ENDIF
  4651. IF NOT EMPTY(m.g_deattype)
  4652.    DO genclause WITH "DEACTIVATE", m.g_deatname, m.g_deattype
  4653. ENDIF
  4654. IF NOT EMPTY(m.g_showtype)
  4655.    DO genclause WITH "SHOW", m.g_showname, m.g_showtype, m.g_showexpr
  4656. ENDIF
  4657.  
  4658. *
  4659. * GENCLAUSE - Generate Read Level Clause keyword.
  4660. *
  4661. * Description:
  4662. * Generate SHOW,ACTIVATE,WHEN, or VALID clause keyword for a
  4663. * READ statement.
  4664. *
  4665. *!*****************************************************************************
  4666. *!
  4667. *!      Procedure: GENCLAUSE
  4668. *!
  4669. *!      Called by: GENREADCLAUSES     (procedure in GENSCRN.PRG)
  4670. *!
  4671. *!*****************************************************************************
  4672. PROCEDURE genclause
  4673. PARAMETER m.keyword, m.name, m.type, m.expr
  4674. PRIVATE m.codename
  4675. \\ ;
  4676. \       <<m.keyword>>
  4677. DO CASE
  4678. CASE m.type = "CODE"
  4679.    \\ <<m.name>>
  4680.    \\()
  4681. CASE m.type = "EXPR"
  4682.    \\ <<stripCR(m.name)>>
  4683. CASE m.type = "BOTH"
  4684.    * This is tricky.  We need to generate the user's expression followed by
  4685.    * a procedure, presumably containing code to handle refreshable SAYS in
  4686.    * a READ ... SHOW clause.  Right now, the name variable contains the
  4687.    * expression.  Emit it, generate a random name for the SHOW snippet, then
  4688.    * record that random name in the m.name field so that we can remember it
  4689.    * later.  The expression needs to come second (due to the boolean short-cutting
  4690.    * optimization in the interpreter).
  4691.    IF EMPTY(m.expr)
  4692.       m.codename = LOWER(SYS(2015))
  4693.       \\ <<m.codename>>() AND (<<stripCR(m.name)>>)
  4694.       m.name     = m.codename
  4695.    ELSE
  4696.       * There was an explicit expression passed to us.  Use it.
  4697.       m.codename = LOWER(SYS(2015))
  4698.       \\ <<m.codename>>() AND (<<stripCR(m.expr)>>)
  4699.       m.name     = m.codename
  4700.    ENDIF
  4701. ENDCASE
  4702.  
  4703. *
  4704. * GENGIVENREAD - Generate another clause on the READ.
  4705. *
  4706. *!*****************************************************************************
  4707. *!
  4708. *!      Procedure: GENGIVENREAD
  4709. *!
  4710. *!      Called by: PLACEREAD          (procedure in GENSCRN.PRG)
  4711. *!
  4712. *!          Calls: SEEKHEADER         (procedure in GENSCRN.PRG)
  4713. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4714. *!
  4715. *!*****************************************************************************
  4716. PROCEDURE gengivenread
  4717. PARAMETER m.screen
  4718. PRIVATE m.i, m.dbalias
  4719. IF m.g_multreads
  4720.    DO seekheader WITH m.screen
  4721.  
  4722.    IF ATC('#READ',setupcode) <> 0
  4723.       DO gendirective WITH ;
  4724.          MLINE(setupcode,ATCLINE('#READ',setupcode)),'#READ'
  4725.    ENDIF
  4726. ELSE
  4727.    FOR m.i = 1 TO m.g_nscreens
  4728.       m.g_screen = m.i
  4729.       m.dbalias = g_screens[m.i,5]
  4730.       SELECT (m.dbalias)
  4731.       DO seekheader WITH m.i
  4732.  
  4733.       IF ATC('#READ',setupcode)<>0
  4734.          DO gendirective WITH ;
  4735.             MLINE(setupcode,ATCLINE('#READ',setupcode)),'#READ'
  4736.          RETURN
  4737.       ENDIF
  4738.    ENDFOR
  4739.    m.g_screen = 0
  4740. ENDIF
  4741.  
  4742. *
  4743. * GENDIRECTIVE - Process #ITSEXPRESSION, #READCLAUSES generator directives.
  4744. *
  4745. *!*****************************************************************************
  4746. *!
  4747. *!      Procedure: GENDIRECTIVE
  4748. *!
  4749. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  4750. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  4751. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  4752. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  4753. *!
  4754. *!          Calls: SKIPWHITESPACE()   (function  in GENSCRN.PRG)
  4755. *!
  4756. *!*****************************************************************************
  4757. PROCEDURE gendirective
  4758. PARAMETER m.line, m.directive
  4759. PRIVATE m.newline
  4760. IF ATC(m.directive,m.line)=1
  4761.    IF UPPER(m.directive) = '#REDE'
  4762.       m.g_redefi = .T.
  4763.       RETURN
  4764.    ENDIF
  4765.    m.newline = skipwhitespace(m.line)
  4766.    IF NOT EMPTY(m.newline)
  4767.       DO CASE
  4768.       CASE UPPER(m.directive) = '#READ'
  4769.          \\ ;
  4770.          \      <<UPPER(m.newline)>>
  4771.       CASE UPPER(m.directive) = '#WCLA'
  4772.          \\ ;
  4773.          \      <<UPPER(m.newline)>>
  4774.       CASE UPPER(m.directive) = '#ITSE'
  4775.          m.g_itse = SUBSTR(m.newline,1,1)
  4776.       ENDCASE
  4777.    ENDIF
  4778. ENDIF
  4779.  
  4780. *
  4781. * SKIPWHITESPACE - Trim all white space from parameter string.
  4782. *
  4783. *!*****************************************************************************
  4784. *!
  4785. *!       Function: SKIPWHITESPACE
  4786. *!
  4787. *!      Called by: PREPWNAMES         (procedure in GENSCRN.PRG)
  4788. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4789. *!
  4790. *!*****************************************************************************
  4791. FUNCTION skipwhitespace
  4792. PARAMETER m.line
  4793. PRIVATE m.whitespace
  4794. m.whitespace = AT(' ',m.line)
  4795. IF m.whitespace = 0
  4796.    m.whitespace = AT(CHR(9),m.line)
  4797. ENDIF
  4798. m.line = ALLTRIM(SUBSTR(m.line,m.whitespace))
  4799. DO WHILE SUBSTR(m.line,1,1) = CHR(9)
  4800.    m.line = ALLTRIM(SUBSTR(m.line, 2))
  4801. ENDDO
  4802. RETURN m.line
  4803.  
  4804. **
  4805. ** Code Generating Various Screen Objects
  4806. **
  4807.  
  4808. *
  4809. * DEFPOPUPS - Define popups used in scrollable list definition.
  4810. *
  4811. * Description:
  4812. * Define popup which is later used in the definition of a
  4813. * scrollable list.
  4814. *
  4815. *!*****************************************************************************
  4816. *!
  4817. *!      Procedure: DEFPOPUPS
  4818. *!
  4819. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  4820. *!
  4821. *!          Calls: GENPOPDEFI         (procedure in GENSCRN.PRG)
  4822. *!
  4823. *!*****************************************************************************
  4824. PROCEDURE defpopups
  4825. PRIVATE m.i, m.dbalias, m.cnt, m.anylists
  4826. m.cnt = 0
  4827. FOR m.i = 1 TO m.g_nscreens
  4828.    m.g_screen = m.i
  4829.    m.anylists = .F.
  4830.    m.dbalias = g_screens[m.i,5]
  4831.    SELECT (m.dbalias)
  4832.    SCAN FOR objtype = c_otlist AND STYLE > 1 AND ;
  4833.          (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4834.       IF NOT m.anylists
  4835.          \
  4836.          \#REGION <<INT(m.i)>>
  4837.          m.anylists = .T.
  4838.          m.g_somepops = .T.
  4839.       ENDIF
  4840.       m.cnt = m.cnt + 1
  4841.       g_popups[m.cnt,1] = m.dbalias
  4842.       g_popups[m.cnt,2] = RECNO()
  4843.       g_popups[m.cnt,3] = LOWER(SYS(2015))
  4844.  
  4845.       IF MOD(m.cnt,25)=0
  4846.          DIMENSION g_popups[ALEN(g_popups,1)+25,3]
  4847.       ENDIF
  4848.  
  4849.       DO genpopdefi
  4850.    ENDSCAN
  4851. ENDFOR
  4852. m.g_screen = 0
  4853.  
  4854. *
  4855. * GENPOPDEFI
  4856. *
  4857. *!*****************************************************************************
  4858. *!
  4859. *!      Procedure: GENPOPDEFI
  4860. *!
  4861. *!      Called by: DEFPOPUPS          (procedure in GENSCRN.PRG)
  4862. *!
  4863. *!*****************************************************************************
  4864. PROCEDURE genpopdefi
  4865. IF m.g_noreadplain
  4866.    RETURN
  4867. ENDIF
  4868.  
  4869. \DEFINE POPUP <<g_popups[m.cnt,3]>> ;
  4870. DO CASE
  4871. CASE STYLE = 2
  4872.    \    PROMPT STRUCTURE
  4873. CASE STYLE = 3
  4874.    \    PROMPT FIELD <<ALLTRIM(Expr)>>
  4875. CASE STYLE = 4
  4876.    \    PROMPT FILES
  4877.    IF NOT EMPTY(expr)
  4878.       \\ LIKE <<ALLTRIM(Expr)>>
  4879.    ENDIF
  4880. ENDCASE
  4881. \\ ;
  4882. \       SCROLL
  4883. IF m.g_genvers = 'DOS' OR m.g_genvers = 'UNIX'
  4884.    \\ ;
  4885.    \    MARGIN ;
  4886.    \    MARK ""
  4887.    \
  4888. ENDIF
  4889. *
  4890. * RELPOPUPS - Generate code to release generated popups.
  4891. *
  4892. * Description:
  4893. * Generate code to release all popups defined by the generator
  4894. * in conjunction with generating scrollable lists.
  4895. *
  4896. *!*****************************************************************************
  4897. *!
  4898. *!      Procedure: RELPOPUPS
  4899. *!
  4900. *!      Called by: GENCLNENVIRON      (procedure in GENSCRN.PRG)
  4901. *!
  4902. *!*****************************************************************************
  4903. PROCEDURE relpopups
  4904. PRIVATE m.popcnt, m.i, m.margin
  4905. m.popcnt = ALEN(g_popups,1)
  4906. m.margin = 16
  4907.  
  4908. IF EMPTY(g_popups[1,1]) OR m.g_noreadplain
  4909.    RETURN
  4910. ENDIF
  4911.  
  4912. \RELEASE POPUPS <<g_popups[1,3]>>
  4913. m.i = 2
  4914. DO WHILE m.i <= m.popcnt
  4915.    IF EMPTY(g_popups[m.i,1])
  4916.       RETURN
  4917.    ENDIF
  4918.    IF m.margin > 60
  4919.       m.margin = 4
  4920.       \\,;
  4921.       \ <<g_popups[m.i,3]>>
  4922.    ELSE
  4923.       \\, <<g_popups[m.i,3]>>
  4924.    ENDIF
  4925.    m.margin = m.margin + 3 + LEN(g_popups[m.i,3])
  4926.    m.i = m.i + 1
  4927. ENDDO
  4928. \
  4929.  
  4930. *
  4931. * DEFWINDOWS - Generate code for windows.
  4932. *
  4933. * Description:
  4934. * Generate code to define windows designed in the screen builder.
  4935. * Process all SCX databases and if window definitions found
  4936. * call GENWINDEFI to define the windows.
  4937. *
  4938. *!*****************************************************************************
  4939. *!
  4940. *!      Procedure: DEFWINDOWS
  4941. *!
  4942. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  4943. *!
  4944. *!          Calls: COMMENTBLOCK       (procedure in GENSCRN.PRG)
  4945. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  4946. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  4947. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  4948. *!
  4949. *!*****************************************************************************
  4950. PROCEDURE defwindows
  4951. PRIVATE m.dbalias, m.pos, m.savearea, m.row, m.col, m.firstfound, m.i
  4952. m.firstfound = .T.
  4953. m.savearea = SELECT()
  4954. FOR m.i = 1 TO m.g_nscreens
  4955.    m.g_screen = m.i
  4956.    m.dbalias = g_screens[m.i,5]
  4957.    SELECT (m.dbalias)
  4958.  
  4959.    SCAN FOR objtype = c_otscreen AND ;
  4960.          (g_screens[m.i, 6] OR platform = g_screens[m.i, 7])
  4961.  
  4962.       IF m.firstfound AND !m.g_noreadplain
  4963.          DO commentblock WITH ""," Window definitions"
  4964.          m.firstfound = .F.
  4965.       ENDIF
  4966.  
  4967.       IF NOT EMPTY(STYLE)
  4968.          IF ATC('#ITSE',setupcode)<>0
  4969.             DO gendirective WITH ;
  4970.                MLINE(setupcode,ATCLINE('#ITSE',setupcode)),'#ITSE'
  4971.          ENDIF
  4972.          IF ATC('#REDE',setupcode)<>0
  4973.             DO gendirective WITH ;
  4974.                MLINE(setupcode,ATCLINE('#REDE',setupcode)),'#REDE'
  4975.          ENDIF
  4976.          DO genwindefi WITH m.i
  4977.       ELSE
  4978.          IF ATC('#ITSE',setupcode)<>0
  4979.             DO gendirective WITH ;
  4980.                MLINE(setupcode,ATCLINE('#ITSE',setupcode)),'#ITSE'
  4981.          ENDIF
  4982.          DO gendesktop WITH m.i
  4983.       ENDIF
  4984.    ENDSCAN
  4985. ENDFOR
  4986. m.g_screen = 0
  4987. SELECT (m.savearea)
  4988.  
  4989. *
  4990. * GENDESKTOP - Generate statements to change the desktop font
  4991. *
  4992. * Description:
  4993. * Generate code to change the desktop font if this screen is on
  4994. * the desktop.  This is done only if the user chose the define window
  4995. * option in the generate dialog.
  4996. *
  4997. *!*****************************************************************************
  4998. *!
  4999. *!      Procedure: GENDESKTOP
  5000. *!
  5001. *!      Called by: DEFWINDOWS         (procedure in GENSCRN.PRG)
  5002. *!
  5003. *!          Calls: WINDOWFROMTO       (procedure in GENSCRN.PRG)
  5004. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  5005. *!               : ANYTITLEORFOOTER   (procedure in GENSCRN.PRG)
  5006. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5007. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5008. *!               : ANYWINDOWCHARS     (procedure in GENSCRN.PRG)
  5009. *!               : ANYBORDER          (procedure in GENSCRN.PRG)
  5010. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  5011. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5012. *!               : ANYICON            (procedure in GENSCRN.PRG)
  5013. *!
  5014. *!*****************************************************************************
  5015. PROCEDURE gendesktop
  5016. PARAMETER m.g_screen
  5017. PRIVATE m.center_flag, m.arrange_flag, m.row, m.col, m.j, m.entries
  5018.  
  5019. IF (g_screens[m.g_screen, 7] != 'WINDOWS' AND g_screens[m.g_screen, 7] != 'MAC')
  5020.    RETURN
  5021. ENDIF
  5022.  
  5023. m.center_flag = .F.
  5024. m.arrange_flag = .F.
  5025.  
  5026. IF NOT m.g_defwin
  5027.    RETURN
  5028. ENDIF
  5029.  
  5030. m.g_moddesktop = .T.
  5031.  
  5032. \MODIFY WINDOW SCREEN ;
  5033.  
  5034. IF g_screens[m.g_screen,6]
  5035.    DO windowfromto
  5036.    IF m.g_genvers = "WINDOWS" OR m.g_genvers = "MAC"
  5037.       \\ ;
  5038.       \ FONT "FoxFont", 9
  5039.    ENDIF
  5040. ELSE
  5041.    SELECT (m.g_projalias)
  5042.    GOTO RECORD g_screens[m.g_screen,3]
  5043.  
  5044.    DO getarrange WITH m.dbalias, m.arrange_flag, m.center_flag
  5045.  
  5046.    DO anytitleorfooter
  5047.    DO anyfont
  5048.    DO anystyle
  5049.    DO anywindowchars
  5050.    DO anyborder
  5051.  
  5052.    IF  !EMPTY(PICTURE)
  5053.       DO anywallpaper
  5054.    ELSE
  5055.       DO anyscheme
  5056.    ENDIF
  5057.    DO anyicon
  5058.  
  5059.    IF (CENTER OR m.center_flag) AND !m.arrange_flag
  5060.       \MOVE WINDOW SCREEN CENTER
  5061.    ENDIF
  5062. ENDIF
  5063. \CLEAR
  5064.  
  5065. *
  5066. * GENWINDEFI - Generate window definition
  5067. *
  5068. * Description:
  5069. * Check to see if window name is unique, if not provide a unique name
  5070. * with the use of SYS(2015) and display a warning message if
  5071. * appropriate.  The window definition is generated only if the
  5072. * user selected that option in the generator dialog.
  5073. *
  5074. *!*****************************************************************************
  5075. *!
  5076. *!      Procedure: GENWINDEFI
  5077. *!
  5078. *!      Called by: DEFWINDOWS         (procedure in GENSCRN.PRG)
  5079. *!
  5080. *!          Calls: UNIQUEWIN()        (function  in GENSCRN.PRG)
  5081. *!               : PUSHINDENT         (procedure in GENSCRN.PRG)
  5082. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  5083. *!               : ANYTITLEORFOOTER   (procedure in GENSCRN.PRG)
  5084. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5085. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5086. *!               : ANYWINDOWCHARS     (procedure in GENSCRN.PRG)
  5087. *!               : ANYBORDER          (procedure in GENSCRN.PRG)
  5088. *!               : ANYWALLPAPER       (procedure in GENSCRN.PRG)
  5089. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5090. *!               : ANYICON            (procedure in GENSCRN.PRG)
  5091. *!               : GENDIRECTIVE       (procedure in GENSCRN.PRG)
  5092. *!               : POPINDENT          (procedure in GENSCRN.PRG)
  5093. *!
  5094. *!*****************************************************************************
  5095. PROCEDURE genwindefi
  5096. PARAMETER m.g_screen
  5097. PRIVATE m.name, m.pos, m.dupname, m.arrange_flag, m.center_flag, m.in_parms, m.j
  5098. m.arrange_flag = .F.
  5099. m.center_flag = .F.
  5100. m.dupname = .F.
  5101. m.name = IIF(!EMPTY(g_screens[m.g_screen,2]), g_screens[m.g_screen,2], LOWER(SYS(2015)))
  5102. m.pos = uniquewin(LOWER(m.name), m.g_nwindows, @g_wndows)
  5103. IF m.pos = 0
  5104.    m.dupname = .T.
  5105.    m.name = LOWER(SYS(2015))
  5106.    g_screens[m.g_screen,2] = m.name
  5107.    m.pos = uniquewin(m.name, m.g_nwindows, @g_wndows)
  5108. ENDIF
  5109.  
  5110. * Insert one row (two elements)
  5111. = AINS(g_wndows, m.pos)
  5112. g_wndows[m.pos,1] = m.name
  5113. g_wndows[m.pos,2] = .F.  && it will get a sequence number in AnyWindows
  5114. m.g_nwindows = m.g_nwindows + 1
  5115.  
  5116. m.g_windows = .T.
  5117. IF NOT m.g_defwin
  5118.    RETURN
  5119. ENDIF
  5120.  
  5121. IF NOT m.g_redefi
  5122.    \IF NOT WEXIST("<<m.name>>")
  5123.    * We can safely omit this extra code if the name was a randomly generated one
  5124.    IF  UPPER(LEFT(m.name,2)) <> UPPER(LEFT(SYS(2015),2))
  5125.       \\ ;
  5126.       \ OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'PJX'))>>" ;
  5127.       \ OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'SCX'))>>" ;
  5128.       \ OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'MNX'))>>" ;
  5129.       \ OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'PRG'))>>" ;
  5130.       \ OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'FRX'))>>" ;
  5131.       \ OR UPPER(WTITLE("<<UPPER(m.name)>>")) == "<<UPPER(forceext(m.name,'QPR'))>>"
  5132.    ENDIF
  5133.    DO pushindent
  5134. ENDIF
  5135. \DEFINE WINDOW <<m.name>> ;
  5136.  
  5137. SELECT (m.g_projalias)
  5138. GOTO RECORD g_screens[m.g_screen,3]
  5139.  
  5140. DO getarrange WITH m.dbalias, m.arrange_flag, m.center_flag
  5141.  
  5142. DO anytitleorfooter
  5143. DO anyfont
  5144. DO anystyle
  5145. DO anywindowchars
  5146. DO anyborder
  5147.  
  5148. IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC')
  5149.    IF TAB
  5150.       \\ ;
  5151.       \ HALFHEIGHT
  5152.    ENDIF
  5153.    IF  !EMPTY(PICTURE)
  5154.       DO anywallpaper
  5155.    ELSE
  5156.       DO anyscheme
  5157.    ENDIF
  5158.    DO anyicon
  5159. ELSE
  5160.    DO anyscheme
  5161. ENDIF
  5162.  
  5163. * If the user defined additional window clauses, put them here
  5164. IF ATC("#WCLA",setupcode) > 0
  5165.    DO gendirective WITH ;
  5166.       MLINE(setupcode,ATCLINE('#WCLA',setupcode)),'#WCLA'
  5167. ENDIF
  5168.  
  5169. * Emit the MOVE WINDOW ... CENTER after all the window clauses have been emitted
  5170. IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC')
  5171.    IF (CENTER OR m.center_flag) AND !m.arrange_flag
  5172.       \MOVE WINDOW <<m.name>> CENTER
  5173.    ENDIF
  5174. ENDIF
  5175.  
  5176. IF !m.g_redefi
  5177.    DO popindent
  5178.    \ENDIF
  5179. ENDIF
  5180. \
  5181.  
  5182. *!*****************************************************************************
  5183. *!
  5184. *!      Procedure: GETARRANGE
  5185. *!
  5186. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  5187. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  5188. *!
  5189. *!          Calls: WINDOWFROMTO       (procedure in GENSCRN.PRG)
  5190. *!
  5191. *!*****************************************************************************
  5192. PROCEDURE getarrange
  5193. PARAMETER m.dbalias, m.arrange_flag, m.center_flag
  5194. PRIVATE m.j, m.pname, m.entries, m.row, m.col
  5195. IF !EMPTY(arranged)
  5196.    m.entries = INT(LEN(arranged)/26)
  5197.    m.j = 1
  5198.    DO WHILE m.j <= m.entries
  5199.       m.pname = ALLTRIM(UPPER(SUBSTR(arranged,(m.j-1)*26+1,8)))
  5200.       m.pname = ALLTRIM(CHRTRAN(m.pname,CHR(0)," "))
  5201.       IF m.pname == m.g_genvers    && found the right one
  5202.          IF INLIST(UPPER(SUBSTR(arranged,(m.j-1)*26 + 9,1)),'Y','T')    && is it arranged?
  5203.             IF INLIST(UPPER(SUBSTR(arranged,(m.j-1)*26 +10,1)),'Y','T') && is it centered?
  5204.                m.center_flag = .T.
  5205.             ELSE
  5206.                m.arrange_flag = .T.
  5207.                m.row = VAL(SUBSTR(arranged,(m.j-1)*26 + 11,8))
  5208.                m.col = VAL(SUBSTR(arranged,(m.j-1)*26 + 19,8))
  5209.             ENDIF
  5210.          ENDIF
  5211.          EXIT
  5212.       ENDIF
  5213.       m.j = m.j + 1
  5214.    ENDDO
  5215. ENDIF
  5216. SELECT (m.dbalias)
  5217. IF m.arrange_flag
  5218.    DO windowfromto WITH m.row, m.col
  5219. ELSE
  5220.    DO windowfromto
  5221. ENDIF
  5222. RETURN
  5223.  
  5224. *
  5225. * GENBOXES - Generate code for boxes.
  5226. *
  5227. * Description:
  5228. * Generate code to display all boxes as they appear on the painted
  5229. * screen(s).  Note since there is no FILL clause on @...TO command
  5230. * we use the command @...BOX whenever the fill option has been chosen.
  5231. * If Fill option is not chosen, then we use the simpler form for
  5232. * generating boxes, @...TO command which supplies us with clauses
  5233. * DOUBLE and PANEL for the box borders.
  5234. *
  5235. *!*****************************************************************************
  5236. *!
  5237. *!      Procedure: GENBOXES
  5238. *!
  5239. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5240. *!
  5241. *!          Calls: ANYPATTERN         (procedure in GENSCRN.PRG)
  5242. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5243. *!               : ANYPEN             (procedure in GENSCRN.PRG)
  5244. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5245. *!
  5246. *!*****************************************************************************
  5247. PROCEDURE genboxes
  5248. PRIVATE m.bottom, m.right, m.thisbox
  5249. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5250.    SET DECIMALS TO 3
  5251.    m.bottom = HEIGHT+vpos
  5252.    m.right = WIDTH+hpos
  5253. ELSE
  5254.    m.bottom = HEIGHT+vpos-1
  5255.    m.right = WIDTH+hpos-1
  5256. ENDIF
  5257. IF (m.g_genvers = 'WINDOWS' OR m.g_genvers = 'MAC')
  5258.    IF fillchar <> c_null AND fillchar <> " "
  5259.       \@ <<Vpos>>,<<Hpos>>,<<m.bottom>>,<<m.right>>
  5260.       DO CASE
  5261.       CASE objcode = c_sgbox
  5262.          m.thisbox = c_single
  5263.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5264.       CASE objcode = c_sgboxd
  5265.          m.thisbox = c_double
  5266.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5267.       CASE objcode = c_sgboxp
  5268.          m.thisbox = c_panel
  5269.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5270.       CASE objcode = c_sgboxc
  5271.          IF boxchar = '"'
  5272.             \\ BOX REPLICATE('<<Boxchar>>',8)
  5273.          ELSE
  5274.             \\ BOX REPLICATE("<<Boxchar>>",8)
  5275.          ENDIF
  5276.          IF fillchar = '"'
  5277.             \\+'<<Fillchar>>'
  5278.          ELSE
  5279.             \\+"<<Fillchar>>"
  5280.          ENDIF
  5281.       ENDCASE
  5282.       RETURN
  5283.    ELSE
  5284.       \@ <<Vpos>>,<<Hpos>> TO <<m.bottom>>,<<m.right>>
  5285.    ENDIF
  5286. ELSE
  5287.    IF fillchar <> c_null
  5288.       \@ <<Vpos>>,<<Hpos>>,<<m.bottom>>,<<m.right>>
  5289.       DO CASE
  5290.       CASE objcode = c_sgbox
  5291.          m.thisbox = c_single
  5292.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5293.       CASE objcode = c_sgboxd
  5294.          m.thisbox = c_double
  5295.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5296.       CASE objcode = c_sgboxp
  5297.          m.thisbox = c_panel
  5298.          \\ BOX "<<m.thisbox>><<Fillchar>>"
  5299.       CASE objcode = c_sgboxc
  5300.          IF boxchar = '"'
  5301.             \\ BOX REPLICATE('<<Boxchar>>',8)
  5302.          ELSE
  5303.             \\ BOX REPLICATE("<<Boxchar>>",8)
  5304.          ENDIF
  5305.          IF fillchar = '"'
  5306.             \\+'<<Fillchar>>'
  5307.          ELSE
  5308.             \\+"<<Fillchar>>"
  5309.          ENDIF
  5310.       ENDCASE
  5311.  
  5312.       IF (!EMPTY(colorpair) OR SCHEME <> 0)
  5313.          * Color the inside of the box if it is filled with something.
  5314.          \@ <<Vpos>>,<<Hpos>> FILL TO <<m.bottom>>,<<m.right>>
  5315.          DO anypattern
  5316.          DO anyscheme
  5317.       ENDIF
  5318.       RETURN
  5319.    ELSE
  5320.       \@ <<Vpos>>,<<Hpos>> TO <<m.bottom>>,<<m.right>>
  5321.    ENDIF
  5322. ENDIF
  5323.  
  5324. SET DECIMALS TO 0
  5325. DO CASE
  5326. CASE objcode = c_sgboxd
  5327.    \\ DOUBLE
  5328. CASE objcode = c_sgboxp
  5329.    \\ PANEL
  5330. CASE objcode = c_sgboxc
  5331.    IF boxchar = '"'
  5332.       \\ '<<Boxchar>>'
  5333.    ELSE
  5334.       \\ "<<Boxchar>>"
  5335.    ENDIF
  5336. ENDCASE
  5337. DO anypattern
  5338. DO anypen
  5339. DO anystyle
  5340. DO anyscheme
  5341.  
  5342. *
  5343. * GENLINES - Generate code for lines.
  5344. *
  5345. * Description:
  5346. * Generate code to display all lines as they appear on the painted
  5347. * screen(s).
  5348. *
  5349. *!*****************************************************************************
  5350. *!
  5351. *!      Procedure: GENLINES
  5352. *!
  5353. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5354. *!
  5355. *!          Calls: ANYPEN             (procedure in GENSCRN.PRG)
  5356. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5357. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5358. *!
  5359. *!*****************************************************************************
  5360. PROCEDURE genlines
  5361. PRIVATE m.x, m.y
  5362. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5363.    SET DECIMALS TO 3
  5364.    IF STYLE = 0
  5365.       m.x = HEIGHT+vpos
  5366.       m.y = hpos
  5367.    ELSE
  5368.       m.x = vpos
  5369.       m.y = WIDTH+hpos
  5370.    ENDIF
  5371. ELSE
  5372.    m.x = HEIGHT+vpos-1
  5373.    m.y = WIDTH+hpos-1
  5374. ENDIF
  5375.  
  5376. \@ <<Vpos>>,<<Hpos>> TO <<m.x>>,<<m.y>>
  5377. SET DECIMALS TO 0
  5378. IF BORDER = 1
  5379.    \\ DOUBLE
  5380. ENDIF
  5381. DO anypen
  5382. DO anystyle
  5383. DO anyscheme
  5384.  
  5385.  
  5386. *
  5387. * GENTEXT - Generate code for text.
  5388. *
  5389. * Description:
  5390. * Generate code that will display the text exactly as it appears
  5391. * in the painted screen(s).
  5392. *
  5393. *!*****************************************************************************
  5394. *!
  5395. *!      Procedure: GENTEXT
  5396. *!
  5397. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5398. *!
  5399. *!          Calls: ANYPICTURE         (procedure in GENSCRN.PRG)
  5400. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5401. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5402. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5403. *!
  5404. *!*****************************************************************************
  5405. PROCEDURE gentext
  5406. PRIVATE m.theexpr, m.occur, m.pos
  5407. m.theexpr = expr
  5408. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5409.    SET DECIMALS TO 3
  5410.    m.occur = 1
  5411.    m.pos = AT(CHR(13), m.theexpr, m.occur)
  5412.    * Sometimes the screen builder surrounds text with single quotes and other
  5413.    * times with double quotes.
  5414.    q1 = LEFT(LTRIM(m.theexpr),1)
  5415.  
  5416.    DO WHILE m.pos > 0
  5417.       DO CASE
  5418.       CASE q1 = "'"
  5419.          m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  5420.             "' + CHR(13) + ;" + CHR(13)  + CHR(9) + CHR(9) + "'" ;
  5421.             + SUBSTR(m.theexpr, m.pos + 1)
  5422.       CASE q1 = '['
  5423.          m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  5424.             "] + CHR(13) + ;" + CHR(13)  + CHR(9) + CHR(9) + "[" ;
  5425.             + SUBSTR(m.theexpr, m.pos + 1)
  5426.       OTHERWISE
  5427.          m.theexpr = LEFT(m.theexpr, m.pos -1) + ;
  5428.             '" + CHR(13) + ;' + CHR(13)  + CHR(9) + CHR(9) + '"' ;
  5429.             + SUBSTR(m.theexpr, m.pos + 1)
  5430.       ENDCASE
  5431.       m.occur = m.occur + 1
  5432.       m.pos = AT(CHR(13), m.theexpr, m.occur)
  5433.    ENDDO
  5434.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>>
  5435.    IF height > 1
  5436.       \\ ;
  5437.       \ SIZE <<Height>>,<<Width>>, <<Spacing>>
  5438.    ENDIF
  5439. ELSE
  5440.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  5441.    \    SIZE <<Height>>,<<Width>>, <<Spacing>>
  5442. ENDIF
  5443.  
  5444. SET DECIMALS TO 0
  5445. DO anypicture
  5446. DO anyfont
  5447. DO anystyle
  5448. DO anyscheme
  5449.  
  5450. *
  5451. * GENFIELDS - Generate fields.
  5452. *
  5453. * Description:
  5454. * Generate code to display SAY, GET, and EDIT statements exactly as they
  5455. * appear in the painted screen(s).
  5456. *
  5457. *!*****************************************************************************
  5458. *!
  5459. *!      Procedure: GENFIELDS
  5460. *!
  5461. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5462. *!
  5463. *!          Calls: ANYFONT            (procedure in GENSCRN.PRG)
  5464. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5465. *!               : ANYPICTURE         (procedure in GENSCRN.PRG)
  5466. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5467. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5468. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  5469. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5470. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5471. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5472. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5473. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5474. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5475. *!
  5476. *!*****************************************************************************
  5477. PROCEDURE genfields
  5478. PRIVATE m.theexpr
  5479. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5480.    SET DECIMALS TO 3
  5481. ENDIF
  5482. DO CASE
  5483. CASE objcode = c_sgsay
  5484.    m.theexpr = expr
  5485.    \@ <<Vpos>>,<<Hpos>> SAY <<m.theexpr>> ;
  5486.    \    SIZE <<Height>>,<<Width>>
  5487.    SET DECIMALS TO 0
  5488.    DO anyfont
  5489.    DO anystyle
  5490.    DO anypicture
  5491.    DO anyscheme
  5492.    RETURN
  5493. CASE objcode = c_sgget
  5494.    \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5495.    \    SIZE <<Height>>,<<Width>>
  5496.    DO elemrange
  5497. CASE objcode = c_sgedit
  5498.    DO gentxtrgn
  5499.    RETURN
  5500. ENDCASE
  5501. SET DECIMALS TO 0
  5502.  
  5503. DO gendefault
  5504. DO anyfont
  5505. DO anystyle
  5506. DO anypicture
  5507. DO anywhen
  5508. DO anyvalid
  5509. DO anymessage
  5510. DO anyerror
  5511. DO anydisabled
  5512. DO anyscheme
  5513.  
  5514. *
  5515. * GENINVBUT - Generate Invisible buttons.
  5516. *
  5517. * Description:
  5518. * Generate code to display invisible buttons exactly as they appear
  5519. * in the painted screen(s).
  5520. *
  5521. *!*****************************************************************************
  5522. *!
  5523. *!      Procedure: GENINVBUT
  5524. *!
  5525. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5526. *!
  5527. *!          Calls: ANYFONT            (procedure in GENSCRN.PRG)
  5528. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5529. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5530. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5531. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5532. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5533. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5534. *!
  5535. *!*****************************************************************************
  5536. PROCEDURE geninvbut
  5537.  
  5538. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5539.    SET DECIMALS TO 3
  5540. ENDIF
  5541. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5542. \       PICTURE <<Picture>> ;
  5543. \       SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5544. \       DEFAULT 0
  5545. SET DECIMALS TO 0
  5546.  
  5547. DO anyfont
  5548. DO anystyle
  5549. DO anywhen
  5550. DO anyvalid
  5551. DO anydisabled
  5552. DO anymessage
  5553. DO anyscheme
  5554.  
  5555. *
  5556. * GENTXTRGN - Generate some statements for text edit region.
  5557. *
  5558. * Description:
  5559. * Generate code to display text edit regions exactly as they
  5560. * appear on the painted screen(s).
  5561. *
  5562. *!*****************************************************************************
  5563. *!
  5564. *!      Procedure: GENTXTRGN
  5565. *!
  5566. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  5567. *!
  5568. *!          Calls: ANYPICTURE         (procedure in GENSCRN.PRG)
  5569. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5570. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5571. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5572. *!               : ANYTAB             (procedure in GENSCRN.PRG)
  5573. *!               : ANYSCROLL          (procedure in GENSCRN.PRG)
  5574. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5575. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5576. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5577. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5578. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5579. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5580. *!
  5581. *!*****************************************************************************
  5582. PROCEDURE gentxtrgn
  5583. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5584.    SET DECIMALS TO 3
  5585. ENDIF
  5586. \@ <<Vpos>>,<<Hpos>> EDIT <<Name>> ;
  5587. \       SIZE <<IIF(Height < 1, 1, Height)>>,<<Width>>,<<Initialnum>>
  5588. SET DECIMALS TO 0
  5589.  
  5590. IF NOT EMPTY(PICTURE)
  5591.    DO anypicture
  5592. ENDIF
  5593. DO gendefault
  5594. DO anyfont
  5595. DO anystyle
  5596. DO anytab
  5597. DO anyscroll
  5598. DO anywhen
  5599. DO anyvalid
  5600. DO anymessage
  5601. DO anyerror
  5602. DO anydisabled
  5603. DO anyscheme
  5604.  
  5605. *
  5606. * GENPUSH - Generate Push buttons.
  5607. *
  5608. * Description:
  5609. * Generate code to display push buttons exactly as they appear
  5610. * in the painted screen(s).
  5611. *
  5612. *!*****************************************************************************
  5613. *!
  5614. *!      Procedure: GENPUSH
  5615. *!
  5616. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5617. *!
  5618. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5619. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5620. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5621. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5622. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5623. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5624. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5625. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5626. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5627. *!
  5628. *!*****************************************************************************
  5629. PROCEDURE genpush
  5630. PRIVATE m.thepicture
  5631.  
  5632. m.thepicture = PICTURE
  5633. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5634.    SET DECIMALS TO 3
  5635. ENDIF
  5636. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5637. DO anybitmapctrl WITH m.thepicture
  5638. \       SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5639. SET DECIMALS TO 0
  5640. \       DEFAULT <<Initialnum>>
  5641. DO anyfont
  5642. DO anystyle
  5643. DO anywhen
  5644. DO anyvalid
  5645. DO anydisabled
  5646. DO anymessage
  5647. DO anyerror
  5648. DO anyscheme
  5649.  
  5650. *
  5651. * GENRADBUT - Generate Radio Buttons.
  5652. *
  5653. * Description:
  5654. * Generate code to display radio buttons exactly as they appear
  5655. * in the painted screen(s).
  5656. *
  5657. *!*****************************************************************************
  5658. *!
  5659. *!      Procedure: GENRADBUT
  5660. *!
  5661. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5662. *!
  5663. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5664. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5665. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5666. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5667. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5668. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5669. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5670. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5671. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5672. *!
  5673. *!*****************************************************************************
  5674. PROCEDURE genradbut
  5675. PRIVATE m.thepicture
  5676.  
  5677. m.thepicture = PICTURE
  5678. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5679.    SET DECIMALS TO 3
  5680. ENDIF
  5681. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5682. DO anybitmapctrl WITH m.thepicture
  5683. \       SIZE <<Height>>,<<Width>>,<<Spacing>> ;
  5684. SET DECIMALS TO 0
  5685. \       DEFAULT <<Initialnum>>
  5686. DO anyfont
  5687. DO anystyle
  5688. DO anywhen
  5689. DO anyvalid
  5690. DO anydisabled
  5691. DO anymessage
  5692. DO anyerror
  5693. DO anyscheme
  5694.  
  5695. *
  5696. * GENCHKBOX - Generate Check Boxes
  5697. *
  5698. * Description:
  5699. * Generate code to display check boxes exactly as they appear
  5700. * in the painted screen(s).
  5701. *
  5702. *!*****************************************************************************
  5703. *!
  5704. *!      Procedure: GENCHKBOX
  5705. *!
  5706. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5707. *!
  5708. *!          Calls: ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  5709. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5710. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5711. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5712. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5713. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5714. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5715. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5716. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5717. *!
  5718. *!*****************************************************************************
  5719. PROCEDURE genchkbox
  5720. PRIVATE m.thepicture
  5721.  
  5722. m.thepicture = PICTURE
  5723. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5724.    SET DECIMALS TO 3
  5725. ENDIF
  5726.  
  5727. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5728. DO anybitmapctrl WITH m.thepicture
  5729. \       SIZE <<Height>>,<<Width>> ;
  5730. SET DECIMALS TO 0
  5731. \       DEFAULT <<Initialnum>>
  5732. DO anyfont
  5733. DO anystyle
  5734. DO anywhen
  5735. DO anyvalid
  5736. DO anydisabled
  5737. DO anymessage
  5738. DO anyerror
  5739. DO anyscheme
  5740.  
  5741. *
  5742. * GENLIST - Generate Scrollable Lists.
  5743. *
  5744. * Description:
  5745. * Generate code to display scrollable lists exactly as they appear
  5746. * in the painted screen(s).
  5747. *
  5748. *!*****************************************************************************
  5749. *!
  5750. *!      Procedure: GENLIST
  5751. *!
  5752. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5753. *!
  5754. *!          Calls: CHOPPICTURE        (procedure in GENSCRN.PRG)
  5755. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5756. *!               : FROMPOPUP          (procedure in GENSCRN.PRG)
  5757. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5758. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5759. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5760. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5761. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5762. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5763. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5764. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5765. *!
  5766. *!*****************************************************************************
  5767. PROCEDURE genlist
  5768. PRIVATE m.pos, m.start
  5769. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5770.    SET DECIMALS TO 3
  5771. ENDIF
  5772. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5773. SET DECIMALS TO 0
  5774. IF NOT EMPTY(PICTURE)
  5775.    \    PICTURE
  5776.    DO choppicture WITH PICTURE
  5777.    \\ ;
  5778. ENDIF
  5779. IF STYLE = 0
  5780.    \    FROM <<Expr>>
  5781.    DO elemrange
  5782.    \\ ;
  5783.    IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5784.       SET DECIMALS TO 3
  5785.    ENDIF
  5786.    \    SIZE <<Height>>,<<Width>> ;
  5787.    SET DECIMALS TO 0
  5788.    \    DEFAULT 1
  5789. ELSE
  5790.    DO frompopup
  5791. ENDIF
  5792.  
  5793. DO anyfont
  5794. DO anystyle
  5795. DO anywhen
  5796. DO anyvalid
  5797. DO anydisabled
  5798. DO anymessage
  5799. DO anyerror
  5800. DO anyscheme
  5801.  
  5802. *
  5803. * GENPICTURE - Generate code for pictures.
  5804. *
  5805. * Description:
  5806. * Generate code to display pictures (bitmaps or bitmaps in general fields).
  5807. *
  5808. *!*****************************************************************************
  5809. *!
  5810. *!      Procedure: GENPICTURE
  5811. *!
  5812. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  5813. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  5814. *!
  5815. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  5816. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5817. *!
  5818. *!*****************************************************************************
  5819. PROCEDURE genpicture
  5820. PRIVATE m.relpath
  5821. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5822.    SET DECIMALS TO 3
  5823.    \@ <<Vpos>>,<<Hpos>> SAY
  5824.    IF STYLE = 0
  5825.       m.relpath = LOWER(findrelpath(SUBSTR(PICTURE,2,LEN(PICTURE)-2)))
  5826.       \\ (LOCFILE("<<m.relpath>>","BMP|ICO", "Where is <<basename(m.relpath)>>?")) BITMAP ;
  5827.    ELSE
  5828.       \\ <<Name>> ;
  5829.    ENDIF
  5830.    \    SIZE <<Height>>,<<Width>>
  5831.  
  5832.    IF CENTER
  5833.       \\ ;
  5834.       \ CENTER
  5835.    ENDIF
  5836.  
  5837.    DO CASE
  5838.    CASE BORDER = 1
  5839.       \\ ;
  5840.       \ ISOMETRIC
  5841.    CASE BORDER = 2
  5842.       \\ ;
  5843.       \ STRETCH
  5844.    ENDCASE
  5845.  
  5846.    SET DECIMALS TO 0
  5847.    DO anystyle
  5848. ENDIF
  5849.  
  5850. *
  5851. * GENSPINNER - Generate Spinners
  5852. *
  5853. * Description:
  5854. * Generate code to display spinners exactly as they appear
  5855. * in the painted screen(s).
  5856. *
  5857. *!*****************************************************************************
  5858. *!
  5859. *!      Procedure: GENSPINNER
  5860. *!
  5861. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5862. *!
  5863. *!          Calls: CHOPPICTURE        (procedure in GENSCRN.PRG)
  5864. *!               : GENDEFAULT         (procedure in GENSCRN.PRG)
  5865. *!               : ELEMRANGE          (procedure in GENSCRN.PRG)
  5866. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  5867. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  5868. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  5869. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  5870. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  5871. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  5872. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  5873. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  5874. *!
  5875. *!*****************************************************************************
  5876. PROCEDURE genspinner
  5877. PRIVATE m.thepicture
  5878.  
  5879. m.thepicture = PICTURE
  5880. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5881.    SET DECIMALS TO 3
  5882. ENDIF
  5883.  
  5884. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  5885. \       SPINNER
  5886.  
  5887. ** Generate the increment value
  5888. IF !EMPTY(initialval)
  5889.    IF INT(VAL(initialval)) <> VAL(initialval)
  5890.       SET DECIMALS TO LEN(initialval) - AT('.',initialval)
  5891.    ENDIF
  5892.    \\ <<VAL(Initialval)>>
  5893.    SET DECIMALS TO 3
  5894. ELSE
  5895.    \\ 1.000
  5896. ENDIF
  5897.  
  5898. ** Generate the minimum value.
  5899. IF !EMPTY(TAG)
  5900.    \\, <<Tag>>
  5901. ELSE
  5902.    IF !EMPTY(tag2)
  5903.       \\,
  5904.    ENDIF
  5905. ENDIF
  5906.  
  5907. ** Generate the maximum value.
  5908. IF !EMPTY(tag2)
  5909.    \\, <<Tag2>>
  5910. ENDIF
  5911. \\ ;
  5912.  
  5913. IF !EMPTY(m.thepicture)
  5914.    \    PICTURE
  5915.    DO choppicture WITH m.thepicture
  5916.    \\ ;
  5917. ENDIF
  5918. \       SIZE <<Height>>, <<Width>>
  5919.  
  5920. ** Put out a default which corresponds to the range of valid values.
  5921. IF !EMPTY(TAG)
  5922.    \\ ;
  5923.    \    DEFAULT <<VAL(Tag)>>
  5924. ELSE
  5925.    IF !EMPTY(tag2)
  5926.       \\ ;
  5927.       \ DEFAULT <<VAL(Tag2)>>
  5928.    ELSE
  5929.       DO gendefault
  5930.    ENDIF
  5931. ENDIF
  5932.  
  5933. DO elemrange
  5934. DO anywhen
  5935. DO anyvalid
  5936. DO anydisabled
  5937. DO anymessage
  5938. DO anyerror
  5939. SET DECIMALS TO 0
  5940. DO anyfont
  5941. DO anystyle
  5942. DO anyscheme
  5943.  
  5944. *
  5945. * FROMPOPUP - Generate code for scrollable list defined from a popup.
  5946. *
  5947. * Description:
  5948. * Generate POPUP <popup name> code as part of a scrollable list
  5949. * definition.  Popup name may either be name explicitly provided by
  5950. * the user or a unique name generated by SYS(2015) function.
  5951. *
  5952. *!*****************************************************************************
  5953. *!
  5954. *!      Procedure: FROMPOPUP
  5955. *!
  5956. *!      Called by: GENLIST            (procedure in GENSCRN.PRG)
  5957. *!
  5958. *!*****************************************************************************
  5959. PROCEDURE frompopup
  5960. PRIVATE m.start, m.pos
  5961. \       POPUP
  5962. IF STYLE < 2
  5963.    IF NOT EMPTY(expr)
  5964.       \\ <<Expr>> ;
  5965.    ENDIF
  5966. ELSE
  5967.    m.start = 1
  5968.    m.pos   = 0
  5969.    DO WHILE .T.
  5970.       m.pos = ASCAN(g_popups, m.dbalias, m.start)
  5971.       IF g_popups[m.pos+1] = RECNO()
  5972.          EXIT
  5973.       ENDIF
  5974.       m.start = m.pos + 3
  5975.    ENDDO
  5976.    \\ <<g_popups[m.pos+2]>> ;
  5977. ENDIF
  5978.  
  5979. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  5980.    SET DECIMALS TO 3
  5981. ENDIF
  5982. \       SIZE <<Height>>,<<Width>> ;
  5983. \       DEFAULT " "
  5984. SET DECIMALS TO 0
  5985.  
  5986. *
  5987. * GENPOPUP - Generate Popups.
  5988. *
  5989. * Description:
  5990. * Generate code to display popups exactly as they appear in the
  5991. * painted screen(s).
  5992. *
  5993. *!*****************************************************************************
  5994. *!
  5995. *!      Procedure: GENPOPUP
  5996. *!
  5997. *!      Called by: BUILDFMT           (procedure in GENSCRN.PRG)
  5998. *!
  5999. *!          Calls: ELEMRANGE          (procedure in GENSCRN.PRG)
  6000. *!               : ANYFONT            (procedure in GENSCRN.PRG)
  6001. *!               : ANYSTYLE           (procedure in GENSCRN.PRG)
  6002. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  6003. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  6004. *!               : ANYDISABLED        (procedure in GENSCRN.PRG)
  6005. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  6006. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  6007. *!               : ANYSCHEME          (procedure in GENSCRN.PRG)
  6008. *!
  6009. *!*****************************************************************************
  6010. PROCEDURE genpopup
  6011. PRIVATE m.thepicture, m.theinitval
  6012.  
  6013. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6014.    SET DECIMALS TO 3
  6015. ENDIF
  6016. \@ <<Vpos>>,<<Hpos>> GET <<Name>> ;
  6017. IF objcode = c_sgget
  6018.    m.thepicture = PICTURE
  6019.    m.theinitval = initialval
  6020.    \    PICTURE <<m.thepicture>> ;
  6021.    \    SIZE <<Height>>,<<Width>> ;
  6022.    \    DEFAULT <<IIF(EMPTY(m.theinitval), '" "', m.theinitval)>>
  6023. ELSE
  6024.    \    PICTURE "@^" ;
  6025.    \    FROM <<Expr>> ;
  6026.    \    SIZE <<Height>>,<<Width>>
  6027.    DO elemrange
  6028.    \\ ;
  6029.    \    DEFAULT 1
  6030. ENDIF
  6031. SET DECIMALS TO 0
  6032.  
  6033. DO anyfont
  6034. DO anystyle
  6035. DO anywhen
  6036. DO anyvalid
  6037. DO anydisabled
  6038. DO anymessage
  6039. DO anyerror
  6040. DO anyscheme
  6041.  
  6042. *
  6043. * ELEMRANGE - Element range clause for popup and scrollable list
  6044. *                               defined form an array.
  6045. *
  6046. *!*****************************************************************************
  6047. *!
  6048. *!      Procedure: ELEMRANGE
  6049. *!
  6050. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6051. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6052. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6053. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6054. *!
  6055. *!          Calls: ADDTOCTRL          (procedure in GENSCRN.PRG)
  6056. *!
  6057. *!*****************************************************************************
  6058. PROCEDURE elemrange
  6059. PRIVATE m.firstelem, m.genericname
  6060. m.firstelem = .F.
  6061. IF NOT EMPTY(rangelo)
  6062.    m.firstelem = .T.
  6063.    \\ ;
  6064.    \    RANGE
  6065.    IF lotype = 0
  6066.       \\ <<ALLTRIM(CHRTRAN(Rangelo,CHR(13)+CHR(10),""))>>
  6067.    ELSE
  6068.       m.genericname = LOWER(SYS(2015))
  6069.       \\ <<m.genericname>>()
  6070.       DO CASE
  6071.       CASE objtype = c_otfield
  6072.          DO addtoctrl WITH m.genericname, "GET Low RANGE", rangelo, name
  6073.       CASE objtype = c_otspinner
  6074.          DO addtoctrl WITH m.genericname, "SPINNER Low RANGE", rangelo, name
  6075.       OTHERWISE
  6076.          DO addtoctrl WITH m.genericname, "Popup From", rangelo, name
  6077.       ENDCASE
  6078.    ENDIF
  6079. ENDIF
  6080. IF NOT EMPTY(rangehi)
  6081.    IF NOT m.firstelem
  6082.       \\ ;
  6083.       \ RANGE ,
  6084.    ELSE
  6085.       \\,
  6086.    ENDIF
  6087.    IF hitype = 0
  6088.       \\ <<CHRTRAN(ALLTRIM(Rangehi),CHR(13)+CHR(10),"")>>
  6089.    ELSE
  6090.       m.genericname = LOWER(SYS(2015))
  6091.       \\ <<m.genericname>>()
  6092.       DO CASE
  6093.       CASE objtype = c_otfield
  6094.          DO addtoctrl WITH m.genericname, "GET High RANGE", rangehi, name
  6095.       CASE objtype = c_otspinner
  6096.          DO addtoctrl WITH m.genericname, "SPINNER High RANGE", rangehi, name
  6097.       OTHERWISE
  6098.          DO addtoctrl WITH m.genericname, "Popup From", rangehi, name
  6099.       ENDCASE
  6100.    ENDIF
  6101. ENDIF
  6102.  
  6103. *
  6104. * GENACTWINDOW - Generate Activate Window Command.
  6105. *
  6106. * Description:
  6107. * Generate the ACTIVATE WINDOW... command.
  6108. *
  6109. *!*****************************************************************************
  6110. *!
  6111. *!      Procedure: GENACTWINDOW
  6112. *!
  6113. *!      Called by: ANYWINDOWS         (procedure in GENSCRN.PRG)
  6114. *!
  6115. *!*****************************************************************************
  6116. PROCEDURE genactwindow
  6117. PARAMETER m.cnt
  6118. IF !m.g_noreadplain
  6119.    IF m.g_lastwindow == g_screens[m.cnt,2]
  6120.       \@ 0,0 CLEAR
  6121.    ENDIF
  6122.    IF m.g_multreads
  6123.       \ACTIVATE WINDOW <<g_screens[m.cnt,2]>>
  6124.       RETURN
  6125.    ENDIF
  6126.  
  6127.    \IF WVISIBLE("<<g_screens[m.cnt,2]>>")
  6128.    \    ACTIVATE WINDOW <<g_screens[m.cnt,2]>> SAME
  6129.    \ELSE
  6130.    \    ACTIVATE WINDOW <<g_screens[m.cnt,2]>> NOSHOW
  6131.    \ENDIF
  6132. ENDIF
  6133.  
  6134. *
  6135. * GENDEFAULT - Generate Default Clause.
  6136. *
  6137. *!*****************************************************************************
  6138. *!
  6139. *!      Procedure: GENDEFAULT
  6140. *!
  6141. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6142. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6143. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6144. *!
  6145. *!*****************************************************************************
  6146. PROCEDURE gendefault
  6147. PRIVATE m.theinitval
  6148. IF EMPTY(initialval) AND EMPTY(fillchar)
  6149.    RETURN
  6150. ENDIF
  6151. \\ ;
  6152. \       DEFAULT
  6153. IF EMPTY(initialval)
  6154.    DO CASE
  6155.    CASE fillchar = "D"
  6156.       \\ {  /  /  }
  6157.    CASE fillchar = "C" OR fillchar = "M" OR fillchar = "G"
  6158.       \\ " "
  6159.    CASE fillchar = "L"
  6160.       \\ .F.
  6161.    CASE fillchar = "N"
  6162.       \\ 0
  6163.    CASE fillchar = "F"
  6164.       \\ 0.0
  6165.    ENDCASE
  6166. ELSE
  6167.    m.theinitval = initialval
  6168.    \\ <<ALLTRIM(m.theinitval)>>
  6169. ENDIF
  6170.  
  6171. **
  6172. **  Procedures Generating Various Clauses for Screen Objects
  6173. **
  6174.  
  6175. *
  6176. * ANYBITMAPCTRL - Parse the picture clause for a bitmap control (Push button, radio button, checkbox) and return it
  6177. *               with LOCAFILE and a relative path in place of each absolute path.
  6178. *
  6179. *!*****************************************************************************
  6180. *!
  6181. *!      Procedure: ANYBITMAPCTRL
  6182. *!
  6183. *!      Called by: GENPUSH            (procedure in GENSCRN.PRG)
  6184. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6185. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6186. *!
  6187. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  6188. *!               : CHOPPICTURE        (procedure in GENSCRN.PRG)
  6189. *!
  6190. *!*****************************************************************************
  6191. PROCEDURE anybitmapctrl
  6192. PARAMETER m.picture
  6193. PRIVATE m.name, m.relpath, m.count
  6194.  
  6195. IF AT("B", SUBSTR(m.picture,1, AT(" ",m.picture))) <> 0
  6196.    \    PICTURE <<LEFT(m.picture, AT(" ",m.picture))>>"
  6197.  
  6198.    m.picture = SUBSTR(m.picture, AT(" ", m.picture)+1)
  6199.    m.picture = LEFT(m.picture, LEN(m.picture)-1)
  6200.    m.count = 0
  6201.  
  6202.    DO WHILE LEN(m.picture) <> 0
  6203.       m.count = m.count + 1
  6204.       IF AT(";", m.picture) <> 0
  6205.          m.name = LEFT(m.picture, AT(";", m.picture)-1)
  6206.          m.picture = SUBSTR(m.picture, AT(";",m.picture)+1)
  6207.       ELSE
  6208.          m.name = m.picture
  6209.          m.picture = ""
  6210.       ENDIF
  6211.  
  6212.       m.relpath = LOWER(findrelpath(m.name))
  6213.       IF m.count = 1
  6214.          \\ + ;
  6215.       ELSE
  6216.          \\ + ";" + ;
  6217.       ENDIF
  6218.       \         (LOCFILE("<<m.relpath>>","BMP|ICO","Where is <<basename(m.relpath)>>?"))
  6219.    ENDDO
  6220.  
  6221.    \\ ;
  6222. ELSE
  6223.    \    PICTURE
  6224.    DO choppicture WITH m.picture
  6225.    \\ ;
  6226. ENDIF
  6227.  
  6228. *
  6229. * CHOPPICTURE - Breaks a Picture clause into multiple 250 character segments to avoid
  6230. *               the maximum string length limit.
  6231. *
  6232. *!*****************************************************************************
  6233. *!
  6234. *!      Procedure: CHOPPICTURE
  6235. *!
  6236. *!      Called by: GENLIST            (procedure in GENSCRN.PRG)
  6237. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6238. *!               : ANYBITMAPCTRL      (procedure in GENSCRN.PRG)
  6239. *!
  6240. *!*****************************************************************************
  6241. PROCEDURE choppicture
  6242. PARAMETER m.pict
  6243. PRIVATE m.quotechar, m.first
  6244. m.quotechar = LEFT(m.pict,1)
  6245. m.first = .T.
  6246.  
  6247. DO WHILE LEN(m.pict) > 250
  6248.    IF m.first
  6249.       \\ <<LEFT(m.pict,250) + m.quotechar>> + ;
  6250.       m.first = .F.
  6251.    ELSE
  6252.       \         <<LEFT(m.pict,250) + m.quotechar>> + ;
  6253.    ENDIF
  6254.    m.pict = m.quotechar + SUBSTR(m.pict,251)
  6255. ENDDO
  6256.  
  6257. IF m.first
  6258.    \\ <<m.pict>>
  6259. ELSE
  6260.    \    <<m.pict>>
  6261. ENDIF
  6262.  
  6263. *
  6264. *
  6265. * ANYDISABLED - Place ENABLE/DISABLE clause.
  6266. *
  6267. *!*****************************************************************************
  6268. *!
  6269. *!      Procedure: ANYDISABLED
  6270. *!
  6271. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6272. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6273. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6274. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6275. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6276. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6277. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6278. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6279. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6280. *!
  6281. *!*****************************************************************************
  6282. PROCEDURE anydisabled
  6283. IF disabled
  6284.    \\ ;
  6285.    \    DISABLE
  6286. ENDIF
  6287.  
  6288. *
  6289. * ANYPICTURE
  6290. *
  6291. *!*****************************************************************************
  6292. *!
  6293. *!      Procedure: ANYPICTURE
  6294. *!
  6295. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6296. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6297. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6298. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6299. *!
  6300. *!*****************************************************************************
  6301. PROCEDURE anypicture
  6302. PRIVATE m.string, m.expr_pos, m.newstring
  6303. IF NOT EMPTY(PICTURE) AND PICTURE <> '" "'
  6304.    \\ ;
  6305.    m.string = SUBSTR(PICTURE,2)   && drop opening quotation mark
  6306.    DO CASE
  6307.    CASE SUBSTR(m.string,1,1) = m.g_itse
  6308.       \ PICTURE <<SUBSTR(m.string,2,RAT(LEFT(picture,1),m.string)-2)>>
  6309.    CASE hasexpr(m.string) > 0 && an #ITSEXPRESSION character somewhere in the middle
  6310.         m.expr_pos = hasexpr(picture)
  6311.         * Emit the first part of the PICTURE
  6312.         \       PICTURE <<LEFT(picture,expr_pos-1)>>
  6313.         * Emit a closing quotation mark, which will be the same as the opening one
  6314.         \\<<LEFT(picture,1)>>
  6315.         * Now emit the expression portion of the picture clause, not including a closing quote
  6316.         \\ + <<SUBSTR(picture,expr_pos+1,LEN(picture)-expr_pos-1))>>
  6317.    OTHERWISE
  6318.       \ PICTURE <<Picture>>
  6319.    ENDCASE
  6320. ENDIF
  6321.  
  6322.  
  6323. FUNCTION hasexpr
  6324. PARAMETER m.thepicture
  6325. RETURN ATC(m.g_itse,m.thepicture)
  6326.  
  6327. *
  6328. * ANYSCROLL - Place Scroll clause if applicable.
  6329. *
  6330. *!*****************************************************************************
  6331. *!
  6332. *!      Procedure: ANYSCROLL
  6333. *!
  6334. *!      Called by: GENTXTRGN          (procedure in GENSCRN.PRG)
  6335. *!
  6336. *!*****************************************************************************
  6337. PROCEDURE anyscroll
  6338. IF scrollbar
  6339.    \\ ;
  6340.    \    SCROLL
  6341. ENDIF
  6342.  
  6343. *
  6344. * ANYTAB - Place Tab clause on an @...EDIT command.
  6345. *
  6346. *!*****************************************************************************
  6347. *!
  6348. *!      Procedure: ANYTAB
  6349. *!
  6350. *!      Called by: GENTXTRGN          (procedure in GENSCRN.PRG)
  6351. *!
  6352. *!*****************************************************************************
  6353. PROCEDURE anytab
  6354. IF TAB
  6355.    \\ ;
  6356.    \    TAB
  6357. ENDIF
  6358.  
  6359. *
  6360. * ANYFONT - Place font clause on an object if in a graphical
  6361. *               environment
  6362. *
  6363. *!*****************************************************************************
  6364. *!
  6365. *!      Procedure: ANYFONT
  6366. *!
  6367. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6368. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6369. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6370. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6371. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6372. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6373. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6374. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6375. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6376. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6377. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6378. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6379. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6380. *!
  6381. *!*****************************************************************************
  6382. PROCEDURE anyfont
  6383. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6384.    \\ ;
  6385.    \    FONT "<<Fontface>>", <<Fontsize>>
  6386. ENDIF
  6387.  
  6388. *
  6389. * ANYSTYLE - Place a Style clause in an object.
  6390. *
  6391. *!*****************************************************************************
  6392. *!
  6393. *!      Procedure: ANYSTYLE
  6394. *!
  6395. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6396. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6397. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6398. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  6399. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6400. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6401. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6402. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6403. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6404. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6405. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6406. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6407. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6408. *!               : GENPICTURE         (procedure in GENSCRN.PRG)
  6409. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6410. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6411. *!
  6412. *!*****************************************************************************
  6413. PROCEDURE anystyle
  6414. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6415.    IF NOT EMPTY(fontstyle) OR mode != 0 OR ;
  6416.          (NOT EMPTY(STYLE) AND objtype != c_otscreen AND ;
  6417.          objtype != c_ottext )
  6418.       \\ ;
  6419.       \ STYLE "
  6420.       DO CASE
  6421.       CASE fontstyle = 1
  6422.          \\B
  6423.       CASE fontstyle = 2
  6424.          \\I
  6425.       CASE fontstyle = 3
  6426.          \\BI
  6427.       ENDCASE
  6428.  
  6429.       IF mode = 1
  6430.          \\T
  6431.       ENDIF
  6432.  
  6433.       IF NOT EMPTY(STYLE) AND objtype != c_otscreen AND ;
  6434.             objtype != c_otlist AND objtype != c_ottext AND ;
  6435.                                                 objtype != c_otpicture
  6436.          \\<<Style>>
  6437.       ENDIF
  6438.       \\"
  6439.    ENDIF
  6440. ENDIF
  6441.  
  6442. *
  6443. * ANYPATTERN - Place a PATTERN clause for boxes.
  6444. *
  6445. *!*****************************************************************************
  6446. *!
  6447. *!      Procedure: ANYPATTERN
  6448. *!
  6449. *!      Called by: GENBOXES           (procedure in GENSCRN.PRG)
  6450. *!
  6451. *!*****************************************************************************
  6452. PROCEDURE anypattern
  6453. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6454.    IF fillpat != 0
  6455.       \\ ;
  6456.       \ PATTERN <<Fillpat>>
  6457.    ENDIF
  6458. ENDIF
  6459.  
  6460. *
  6461. * ANYSCHEME - Place Color Scheme clause if applicable.
  6462. *
  6463. *!*****************************************************************************
  6464. *!
  6465. *!      Procedure: ANYSCHEME
  6466. *!
  6467. *!      Called by: PLACESAYS          (procedure in GENSCRN.PRG)
  6468. *!               : GENDESKTOP         (procedure in GENSCRN.PRG)
  6469. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6470. *!               : GENBOXES           (procedure in GENSCRN.PRG)
  6471. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6472. *!               : GENTEXT            (procedure in GENSCRN.PRG)
  6473. *!               : GENFIELDS          (procedure in GENSCRN.PRG)
  6474. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6475. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6476. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6477. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6478. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6479. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6480. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6481. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6482. *!
  6483. *!*****************************************************************************
  6484. PROCEDURE anyscheme
  6485.  
  6486. IF NOT EMPTY(colorpair)
  6487.    \\ ;
  6488.    \    COLOR <<Colorpair>>
  6489.    RETURN
  6490. ENDIF
  6491. IF SCHEME <> 0
  6492.    \\ ;
  6493.    \    COLOR SCHEME <<Scheme>>
  6494.    IF objtype = c_otpopup AND scheme2<>0
  6495.       \\, <<Scheme2>>
  6496.    ENDIF
  6497. ELSE
  6498.    IF m.g_defasch2 <> 0
  6499.       DO CASE
  6500.       CASE objtype = c_ottext AND HEIGHT > 1
  6501.          \\ ;
  6502.          \      COLOR SCHEME <<m.g_defasch2>>
  6503.       CASE objtype = c_otlist
  6504.          \\ ;
  6505.          \      COLOR SCHEME <<m.g_defasch2>>
  6506.       CASE objtype = c_otpopup
  6507.          \\ ;
  6508.          \      COLOR SCHEME <<m.g_defasch1>>, <<m.g_defasch2>>
  6509.       ENDCASE
  6510.    ELSE
  6511.       IF (g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC' ) ;
  6512.             AND ((ObjTYpe = c_otscreen AND fillred >=0) ;
  6513.              OR (ObjType <> c_otscreen AND (penred >= 0 OR fillred >= 0)) )
  6514.          m.ctrlflag = .F.   && .T. if this is a control-type object (e.g., radio button)
  6515.          \\ ;
  6516.          \      COLOR
  6517.          DO CASE
  6518.          CASE INLIST(objtype,c_otfield,c_otspinner)
  6519.             ** Field or spinner - color pair 2
  6520.             DO CASE
  6521.             CASE objcode = c_sgget OR objcode = c_sgedit
  6522.                \\ ,RGB(
  6523.             CASE objcode = c_sgsay
  6524.                \\ RGB(
  6525.             CASE objcode = c_sgfrom
  6526.                \\ ,,,,,,,,RGB(
  6527.             ENDCASE
  6528.  
  6529.          CASE objtype = c_otlist
  6530.             m.ctrlflag = .T.    && remember that this is a control object
  6531.             \\ RGB(
  6532.  
  6533.  
  6534.          CASE objtype = c_ottext OR objtype = c_otscreen OR ;
  6535.                objtype = c_otbox OR objtype = c_otline
  6536.             ** Text, Box, Line, or Screen - color pair 1
  6537.             \\ RGB(
  6538.  
  6539.          OTHERWISE
  6540.             m.ctrlflag = .T.    && remember that this is a control object
  6541.             \\ ,,,,,,,,RGB(
  6542.          ENDCASE
  6543.  
  6544.          IF penred >= 0
  6545.             \\<<Penred>>,<<Pengreen>>,<<Penblue>>,
  6546.          ELSE
  6547.             \\,,,
  6548.          ENDIF
  6549.          IF fillred >= 0
  6550.             \\<<Fillred>>,<<Fillgreen>>,<<Fillblue>>)
  6551.          ELSE
  6552.             \\,,,)
  6553.          ENDIF
  6554.  
  6555.          IF m.ctrlflag AND INLIST(objtype, c_otradbut, c_otchkbox, c_otpopup,c_otlist)
  6556.             * Add one more RGB clause to control the disabled colors for control
  6557.             * objects such as radio buttons, check boxes, popups, etc.
  6558.             \\,RGB(
  6559.             IF penred >= 0
  6560.                \\<<Penred>>,<<Pengreen>>,<<Penblue>>,
  6561.             ELSE
  6562.                \\,,,
  6563.             ENDIF
  6564.             IF fillred >= 0
  6565.                \\<<Fillred>>,<<Fillgreen>>,<<Fillblue>>)
  6566.             ELSE
  6567.                \\,,,)
  6568.             ENDIF
  6569.          ENDIF
  6570.       ENDIF
  6571.    ENDIF
  6572. ENDIF
  6573.  
  6574. *
  6575. * ANYPEN - Place Color Scheme clause if applicable.
  6576. *
  6577. *!*****************************************************************************
  6578. *!
  6579. *!      Procedure: ANYPEN
  6580. *!
  6581. *!      Called by: GENBOXES           (procedure in GENSCRN.PRG)
  6582. *!               : GENLINES           (procedure in GENSCRN.PRG)
  6583. *!
  6584. *!*****************************************************************************
  6585. PROCEDURE anypen
  6586. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6587.    \\ ;
  6588.    \    PEN <<Pensize>>, <<Penpat>>
  6589. ENDIF
  6590.  
  6591. *
  6592. * ANYVALID - Place Valid clause if applicable.
  6593. *
  6594. *!*****************************************************************************
  6595. *!
  6596. *!      Procedure: ANYVALID
  6597. *!
  6598. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6599. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6600. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6601. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6602. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6603. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6604. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6605. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6606. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6607. *!
  6608. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6609. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6610. *!
  6611. *!*****************************************************************************
  6612. PROCEDURE anyvalid
  6613. PRIVATE m.genericname, m.valid
  6614. IF NOT EMPTY(VALID)
  6615.    \\ ;
  6616.    IF validtype = 0
  6617.       m.valid = VALID
  6618.       \ VALID <<stripcr(m.valid)>>
  6619.    ELSE
  6620.       m.genericname = getcname(VALID)
  6621.       \ VALID <<m.genericname>>()
  6622.       DO addtoctrl WITH m.genericname, "VALID", VALID, name
  6623.    ENDIF
  6624. ENDIF
  6625.  
  6626. *
  6627. * ANYTITLEORFOOTER - Place Window Title/Footer clause.
  6628. *
  6629. *!*****************************************************************************
  6630. *!
  6631. *!      Procedure: ANYTITLEORFOOTER
  6632. *!
  6633. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6634. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6635. *!
  6636. *!*****************************************************************************
  6637. PROCEDURE anytitleorfooter
  6638. PRIVATE m.string, m.thetag
  6639. IF NOT EMPTY(TAG)
  6640.    \\ ;
  6641.    m.string = SUBSTR(TAG,2)
  6642.    IF SUBSTR(m.string,1,1) = m.g_itse
  6643.       \ TITLE <<SUBSTR(m.string, 2, RAT('"',m.string)-2)>>
  6644.    ELSE
  6645.       m.thetag = TAG
  6646.       \ TITLE <<m.thetag>>
  6647.    ENDIF
  6648. ENDIF
  6649. IF NOT EMPTY(tag2)
  6650.    \\ ;
  6651.    m.string = SUBSTR(tag2,2)
  6652.    IF SUBSTR(m.string,1,1) = m.g_itse
  6653.       \ FOOTER <<SUBSTR(m.string, 2, RAT('"',m.string)-2)>>
  6654.    ELSE
  6655.       m.thetag = tag2
  6656.       \ FOOTER <<m.thetag>>
  6657.    ENDIF
  6658. ENDIF
  6659.  
  6660.  
  6661. *
  6662. * ANYWHEN - Place a When clause in a Get field.
  6663. *
  6664. *!*****************************************************************************
  6665. *!
  6666. *!      Procedure: ANYWHEN
  6667. *!
  6668. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6669. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6670. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6671. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6672. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6673. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6674. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6675. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6676. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6677. *!
  6678. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6679. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6680. *!
  6681. *!*****************************************************************************
  6682. PROCEDURE anywhen
  6683. PRIVATE m.genericname, m.when
  6684. IF EMPTY(WHEN)
  6685.    RETURN
  6686. ENDIF
  6687. \\ ;
  6688. IF whentype = 0
  6689.    m.when = WHEN
  6690.    \    WHEN <<stripcr(m.when)>>
  6691. ELSE
  6692.    m.genericname = getcname(WHEN)
  6693.    \    WHEN <<m.genericname>>()
  6694.    DO addtoctrl WITH m.genericname, "WHEN", WHEN, name
  6695. ENDIF
  6696.  
  6697. *
  6698. * ANYMESSAGE - Place a message clause whenever appropriate.
  6699. *
  6700. *!*****************************************************************************
  6701. *!
  6702. *!      Procedure: ANYMESSAGE
  6703. *!
  6704. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6705. *!               : GENINVBUT          (procedure in GENSCRN.PRG)
  6706. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6707. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6708. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6709. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6710. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6711. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6712. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6713. *!
  6714. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6715. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6716. *!
  6717. *!*****************************************************************************
  6718. PROCEDURE anymessage
  6719. PRIVATE m.genericname, m.mess
  6720. IF EMPTY(MESSAGE)
  6721.    RETURN
  6722. ENDIF
  6723. \\ ;
  6724. IF messtype = 0
  6725.    m.mess = MESSAGE
  6726.    \    MESSAGE
  6727.    \\ <<stripcr(m.mess)>>
  6728. ELSE
  6729.    m.genericname = getcname(MESSAGE)
  6730.    \    MESSAGE <<m.genericname>>()
  6731.    DO addtoctrl WITH m.genericname, "MESSAGE", MESSAGE, name
  6732. ENDIF
  6733.  
  6734. *
  6735. * ANYERROR - Place an error clause whenever appropriate.
  6736. *
  6737. *!*****************************************************************************
  6738. *!
  6739. *!      Procedure: ANYERROR
  6740. *!
  6741. *!      Called by: GENFIELDS          (procedure in GENSCRN.PRG)
  6742. *!               : GENTXTRGN          (procedure in GENSCRN.PRG)
  6743. *!               : GENPUSH            (procedure in GENSCRN.PRG)
  6744. *!               : GENRADBUT          (procedure in GENSCRN.PRG)
  6745. *!               : GENCHKBOX          (procedure in GENSCRN.PRG)
  6746. *!               : GENLIST            (procedure in GENSCRN.PRG)
  6747. *!               : GENSPINNER         (procedure in GENSCRN.PRG)
  6748. *!               : GENPOPUP           (procedure in GENSCRN.PRG)
  6749. *!
  6750. *!          Calls: GETCNAME()         (function  in GENSCRN.PRG)
  6751. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  6752. *!
  6753. *!*****************************************************************************
  6754. PROCEDURE anyerror
  6755. PRIVATE m.genericname, m.err
  6756. IF EMPTY(ERROR)
  6757.    RETURN
  6758. ENDIF
  6759. \\ ;
  6760. IF errortype = 0
  6761.    m.err = ERROR
  6762.    \    ERROR
  6763.    \\ <<stripcr(m.err)>>
  6764. ELSE
  6765.    m.genericname = getcname(ERROR)
  6766.    \    ERROR <<m.genericname>>()
  6767.    DO addtoctrl WITH m.genericname, "ERROR", ERROR, name
  6768. ENDIF
  6769.  
  6770. *
  6771. * ANYFILL - Place the Fill clause whenever appropriate.
  6772. *
  6773. *!*****************************************************************************
  6774. *!
  6775. *!      Procedure: ANYFILL
  6776. *!
  6777. *!*****************************************************************************
  6778. PROCEDURE anyfill
  6779. IF fillchar <> c_null
  6780.    \\ ;
  6781.    \    FILL "<<Fillchar>>"
  6782. ENDIF
  6783.  
  6784. *
  6785. * ANYWINDOWCHARS - Place window characteristics options.
  6786. *
  6787. * Description:
  6788. * Place the FLOAT, GROW, CLOSE, ZOOM, SHADOW, and MINIMIZE clauses
  6789. * for a window painted by the user.
  6790. *
  6791. *!*****************************************************************************
  6792. *!
  6793. *!      Procedure: ANYWINDOWCHARS
  6794. *!
  6795. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6796. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6797. *!
  6798. *!*****************************************************************************
  6799. PROCEDURE anywindowchars
  6800. \\ ;
  6801. \       <<IIF(Float, "FLOAT ;", "NOFLOAT ;")>>
  6802. \       <<IIF(Close, "CLOSE", "NOCLOSE")>>
  6803. IF SHADOW
  6804.    \\ ;
  6805.    \    SHADOW
  6806. ENDIF
  6807. IF MINIMIZE
  6808.    \\ ;
  6809.    \    MINIMIZE
  6810. ELSE
  6811.    \\ ;
  6812.    \    NOMINIMIZE
  6813. ENDIF
  6814.  
  6815. *
  6816. * ANYBORDER - Place Border type clause on a box.
  6817. *
  6818. * Description:
  6819. * Place border type clause on a box depending on the setting of
  6820. * the field Border.
  6821. *
  6822. *!*****************************************************************************
  6823. *!
  6824. *!      Procedure: ANYBORDER
  6825. *!
  6826. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6827. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6828. *!
  6829. *!*****************************************************************************
  6830. PROCEDURE anyborder
  6831. IF BORDER<>1
  6832.    \\ ;
  6833. ENDIF
  6834.  
  6835. DO CASE
  6836. CASE BORDER = 0
  6837.    \    NONE
  6838. CASE BORDER = 2
  6839.    \    DOUBLE
  6840. CASE BORDER = 3
  6841.    \    PANEL
  6842. CASE BORDER = 4
  6843.    \    SYSTEM
  6844. ENDCASE
  6845.  
  6846. *
  6847. * ANYWALLPAPER - Place FILL FILE clause on any window.
  6848. *
  6849. *!*****************************************************************************
  6850. *!
  6851. *!      Procedure: ANYWALLPAPER
  6852. *!
  6853. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6854. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6855. *!
  6856. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  6857. *!
  6858. *!*****************************************************************************
  6859. PROCEDURE anywallpaper
  6860. IF !EMPTY(PICTURE)
  6861.    m.relpath = findrelpath(SUBSTR(PICTURE, 2, LEN(PICTURE) - 2))
  6862.    \\ ;
  6863.    \    FILL FILE LOCFILE("<<m.relpath>>","BMP|ICO", ;
  6864.    \            "Where is <<LOWER(basename(m.relpath))>>?")
  6865. ENDIF
  6866.  
  6867. *
  6868. * ANYICON - Place ICON FILE clause on any window.
  6869. *
  6870. *!*****************************************************************************
  6871. *!
  6872. *!      Procedure: ANYICON
  6873. *!
  6874. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6875. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  6876. *!
  6877. *!          Calls: FINDRELPATH()      (function  in GENSCRN.PRG)
  6878. *!
  6879. *!*****************************************************************************
  6880. PROCEDURE anyicon
  6881. IF !EMPTY(ORDER) AND ORDER <> '""'
  6882.    m.relpath = findrelpath(SUBSTR(ORDER, 2, LEN(ORDER) - 2))
  6883.    \\ ;
  6884.    \    ICON FILE LOCFILE("<<m.relpath>>","ICO", ;
  6885.    \            "Where is <<LOWER(basename(m.relpath))>>?")
  6886. ENDIF
  6887.  
  6888. *
  6889. * WINDOWFROMTO - Place FROM...TO clause on any window.
  6890. *
  6891. * Description:
  6892. * Place FROM...TO clause on any window designed in the screen
  6893. * painter.  If window is to be centered, then adjust the coordinates
  6894. * accordingly.
  6895. *
  6896. *!*****************************************************************************
  6897. *!
  6898. *!      Procedure: WINDOWFROMTO
  6899. *!
  6900. *!      Called by: GENDESKTOP         (procedure in GENSCRN.PRG)
  6901. *!               : GETARRANGE         (procedure in GENSCRN.PRG)
  6902. *!
  6903. *!*****************************************************************************
  6904. PROCEDURE windowfromto
  6905. PARAMETER m.xcoord, m.ycoord
  6906. IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6907.    SET DECIMALS TO 3
  6908. ENDIF
  6909. IF PARAMETERS() = 0
  6910.    IF CENTER
  6911.       IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6912.          \      AT  <<Vpos>>, <<Hpos>>  ;
  6913.          \      SIZE <<Height>>,<<Width>>
  6914.       ELSE
  6915.          \      FROM INT((SROW()-<<Height>>)/2),
  6916.          \\INT((SCOL()-<<Width>>)/2) ;
  6917.          \      TO INT((SROW()-<<Height>>)/2)+<<Height-1>>,
  6918.          \\INT((SCOL()-<<Width>>)/2)+<<Width-1>>
  6919.       ENDIF
  6920.    ELSE
  6921.       IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6922.          \      AT <<Vpos>>, <<Hpos>> ;
  6923.          \      SIZE <<Height>>,<<Width>>
  6924.       ELSE
  6925.          \      FROM <<Vpos>>, <<Hpos>> ;
  6926.          \      TO <<Height+Vpos-1>>,<<Width+Hpos-1>>
  6927.       ENDIF
  6928.    ENDIF
  6929. ELSE
  6930.    IF g_screens[m.g_screen, 7] = 'WINDOWS' OR g_screens[m.g_screen, 7] = 'MAC'
  6931.       \ AT <<m.xcoord>>, <<m.ycoord>> ;
  6932.       \ SIZE <<Height>>,<<Width>>
  6933.    ELSE
  6934.       \ FROM <<m.xcoord>>, <<m.ycoord>> ;
  6935.       \ TO <<Height+m.xcoord-1>>,<<Width+m.ycoord-1>>
  6936.    ENDIF
  6937. ENDIF
  6938. SET DECIMALS TO 0
  6939.  
  6940. **
  6941. ** Code Generating Documentation in Control and Format files.
  6942. **
  6943.  
  6944. *
  6945. * HEADER - Generate application program's header.
  6946. *
  6947. * Description:
  6948. * As a part of the application's header generate program name, name
  6949. * of the author of the program, copyright notice, company name and
  6950. * address, and the word 'Description:' which will be followed with
  6951. * the application description generated by a separate procedure.
  6952. *
  6953. *!*****************************************************************************
  6954. *!
  6955. *!      Procedure: HEADER
  6956. *!
  6957. *!      Called by: BUILDCTRL          (procedure in GENSCRN.PRG)
  6958. *!
  6959. *!*****************************************************************************
  6960. PROCEDURE HEADER
  6961. IF LEN(_PRETEXT) <> 0
  6962.    \
  6963. ENDIF
  6964. \\*       <<m.g_corn1>><<REPLICATE(m.g_horiz,57)>><<m.g_corn2>>
  6965. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  6966. \*       <<m.g_verti1>> <<DATE()>>
  6967. \\<<PADC(UPPER(ALLTRIM(strippath(m.g_outfile))),IIF(SET("CENTURY")="ON",35,37))," ")>>
  6968. \\  <<TIME()>> <<m.g_verti2>>
  6969. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  6970. \*       <<m.g_corn5>><<REPLICATE(m.g_horiz,57)>><<m.g_corn6>>
  6971. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  6972. \*       <<m.g_verti1>> <<m.g_devauthor>>
  6973. \\<<REPLICATE(" ",56-LEN(m.g_devauthor))>><<m.g_verti2>>
  6974. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  6975. \*       <<m.g_verti1>>
  6976. \\ Copyright (c) <<YEAR(DATE())>>
  6977. IF LEN(ALLTRIM(m.g_devcompany)) <= 36
  6978.    \\ <<ALLTRIM(m.g_devcompany)>>
  6979.    \\<<REPLICATE(" ",37-LEN(ALLTRIM(m.g_devcompany)))>>
  6980.    \\<<m.g_verti2>>
  6981. ELSE
  6982.    \\ <<REPLICATE(" ",37)>><<m.g_verti2>>
  6983.    \*       <<m.g_verti1>> <<m.g_devcompany>>
  6984.    \\<<REPLICATE(" ",56-LEN(m.g_devcompany))>><<m.g_verti2>>
  6985. ENDIF
  6986. \*       <<m.g_verti1>> <<m.g_devaddress>>
  6987. \\<<REPLICATE(" ",56-LEN(m.g_devaddress))>><<m.g_verti2>>
  6988.  
  6989. \*       <<m.g_verti1>> <<ALLTRIM(m.g_devcity)>>, <<m.g_devstate>>
  6990. \\  <<ALLTRIM(m.g_devzip)>>
  6991. \\<<REPLICATE(" ",50-(LEN(ALLTRIM(m.g_devcity)+ALLTRIM(m.g_devzip))))>>
  6992. \\<<m.g_verti2>>
  6993.  
  6994. IF !INLIST(ALLTRIM(UPPER(m.g_devctry)),"USA","COUNTRY") AND !EMPTY(m.g_devctry)
  6995.    \*       <<m.g_verti1>> <<ALLTRIM(m.g_devctry)>>
  6996.    \\<<REPLICATE(" ",50-(LEN(ALLTRIM(m.g_devctry))))>>
  6997.    \\<<m.g_verti2>>
  6998. ENDIF
  6999.  
  7000. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7001. \*       <<m.g_verti1>> Description:
  7002. \\                                            <<m.g_verti2>>
  7003. \*       <<m.g_verti1>>
  7004. \\ This program was automatically generated by GENSCRN.
  7005. \\    <<m.g_verti2>>
  7006. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7007. \*       <<m.g_corn3>><<REPLICATE(m.g_horiz,57)>><<m.g_corn4>>
  7008. \
  7009.  
  7010. *
  7011. * GENFUNCHEADER - Generate Comment for Function/Procedure.
  7012. *
  7013. *!*****************************************************************************
  7014. *!
  7015. *!      Procedure: GENFUNCHEADER
  7016. *!
  7017. *!      Called by: VALICLAUSE         (procedure in GENSCRN.PRG)
  7018. *!               : WHENCLAUSE         (procedure in GENSCRN.PRG)
  7019. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7020. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7021. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7022. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  7023. *!
  7024. *!*****************************************************************************
  7025. PROCEDURE genfuncheader
  7026. PARAMETER m.procname, m.from, m.readlevel, m.varname
  7027. m.g_snippcnt = m.g_snippcnt + 1
  7028. \
  7029. \*       <<m.g_corn1>><<REPLICATE(m.g_horiz,57)>><<m.g_corn2>>
  7030. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7031. IF m.readlevel
  7032.    \*       <<m.g_verti1>>
  7033.    \\ <<UPPER(m.procname)>>           <<m.from>>
  7034.    \\<<REPLICATE(" ",45-LEN(m.procname+m.from))>><<m.g_verti2>>
  7035. ELSE
  7036.    \*       <<m.g_verti1>>
  7037.    \\ <<UPPER(m.procname)>>           <<m.varname>> <<m.from>>
  7038.    \\<<REPLICATE(" ",44-LEN(m.procname+m.varname+m.from))>><<m.g_verti2>>
  7039. ENDIF
  7040. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7041. \*       <<m.g_verti1>> Function Origin:
  7042. \\<<REPLICATE(" ",40)>><<m.g_verti2>>
  7043. IF m.readlevel
  7044.    \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7045.    \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7046.    \*       <<m.g_verti1>> From Platform:
  7047.    \\       <<VersionCap(m.g_genvers)>>
  7048.    \\<<REPLICATE(" ",35-LEN(VersionCap(m.g_genvers)))>>
  7049.    \\<<m.g_verti2>>
  7050.    \*       <<m.g_verti1>> From Screen:
  7051.    IF m.g_nscreens > 1 AND NOT m.g_multread
  7052.       \\         Multiple Screens
  7053.       \\<<REPLICATE(" ",19)>><<m.g_verti2>>
  7054.    ELSE
  7055.       \\         <<basename(SYS(2014,DBF()))>>
  7056.       \\<<REPLICATE(" ",35-LEN(basename(SYS(2014,DBF()))))>>
  7057.       \\<<m.g_verti2>>
  7058.    ENDIF
  7059.    \*       <<m.g_verti1>> Called By:           READ Statement
  7060.    \\<<REPLICATE(" ",21)>><<m.g_verti2>>
  7061.    \*       <<m.g_verti1>> Snippet Number:
  7062.    \\      <<ALLTRIM(STR(m.g_snippcnt,2))>>
  7063.    \\<<REPLICATE(" ",35-LEN(ALLTRIM(STR(m.g_snippcnt,2))))>><<m.g_verti2>>
  7064.    \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7065.    \*       <<m.g_corn3>><<REPLICATE(m.g_horiz,57)>><<m.g_corn4>>
  7066.    \*
  7067.    RETURN
  7068. ENDIF
  7069. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7070. \*       <<m.g_verti1>> From Platform:
  7071. \\       <<VersionCap(m.g_genvers)>>
  7072. \\<<REPLICATE(" ",35-LEN(VersionCap(m.g_genvers)))>>
  7073. \\<<m.g_verti2>>
  7074. \*       <<m.g_verti1>> From Screen:
  7075. \\         <<basename(SYS(2014,DBF()))>>
  7076. \\,     Record Number:  <<STR(RECNO(),3)>>
  7077. \\<<REPLICATE(" ",10-LEN(basename(SYS(2014,DBF())+STR(RECNO(),3))))>>
  7078. \\<<m.g_verti2>>
  7079. IF NOT EMPTY(m.varname)
  7080.    \*       <<m.g_verti1>> Variable:            <<m.varname>>
  7081.    \\<<REPLICATE(" ",35-LEN(m.varname))>><<m.g_verti2>>
  7082. ENDIF
  7083. \*       <<m.g_verti1>> Called By:           <<m.from+" Clause">>
  7084. \\<<REPLICATE(" ",35-LEN(m.from+" Clause"))>><<m.g_verti2>>
  7085. IF OBJECT(objtype) <> ""
  7086.    \*       <<m.g_verti1>> Object Type:
  7087.    \\         <<Object(Objtype)>>
  7088.    \\<<REPLICATE(" ",35-LEN(Object(Objtype)))>><<m.g_verti2>>
  7089. ENDIF
  7090. \*       <<m.g_verti1>> Snippet Number:
  7091. \\      <<ALLTRIM(STR(m.g_snippcnt,3))>>
  7092. \\<<REPLICATE(" ",35-LEN(ALLTRIM(STR(m.g_snippcnt,3))))>><<m.g_verti2>>
  7093. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7094. \*       <<m.g_corn3>><<REPLICATE(m.g_horiz,57)>><<m.g_corn4>>
  7095. \*
  7096.  
  7097. *
  7098. * COMMENTBLOCK - Generate a comment block.
  7099. *
  7100. *!*****************************************************************************
  7101. *!
  7102. *!      Procedure: COMMENTBLOCK
  7103. *!
  7104. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  7105. *!               : PUTPROCHEAD        (procedure in GENSCRN.PRG)
  7106. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  7107. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  7108. *!               : GENCLOSEDBFS       (procedure in GENSCRN.PRG)
  7109. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  7110. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  7111. *!               : PLACEREAD          (procedure in GENSCRN.PRG)
  7112. *!               : DEFWINDOWS         (procedure in GENSCRN.PRG)
  7113. *!
  7114. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  7115. *!               : VERSIONCAP()       (function  in GENSCRN.PRG)
  7116. *!
  7117. *!*****************************************************************************
  7118. PROCEDURE commentblock
  7119. PARAMETER m.dbalias, m.string
  7120. PRIVATE m.msg
  7121. IF !EMPTY(basename(m.dbalias))
  7122.    m.msg = basename(m.dbalias)+"/"+versioncap(g_genvers)+m.string
  7123. ELSE
  7124.    m.msg = versioncap(g_genvers)+m.string
  7125. ENDIF
  7126. \
  7127. \*       <<m.g_corn1>><<REPLICATE(m.g_horiz,57)>><<m.g_corn2>>
  7128. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7129. \*       <<m.g_verti1>>
  7130. \\ <<PADC(m.msg,55," ")>>
  7131. \\ <<m.g_verti2>>
  7132. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7133. \*       <<m.g_corn3>><<REPLICATE(m.g_horiz,57)>><<m.g_corn4>>
  7134. \*
  7135. \
  7136.  
  7137. *
  7138. * PROCCOMMENTBLOCK - Generate a procedure comment block.
  7139. *
  7140. *!*****************************************************************************
  7141. *!
  7142. *!      Procedure: PROCCOMMENTBLOCK
  7143. *!
  7144. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  7145. *!
  7146. *!          Calls: BASENAME()         (function  in GENSCRN.PRG)
  7147. *!
  7148. *!*****************************************************************************
  7149. PROCEDURE proccommentblock
  7150. PARAMETER m.dbalias, m.string
  7151. PRIVATE m.msg
  7152. m.msg = basename(m.dbalias)+m.string
  7153. \
  7154. \*       <<m.g_corn1>><<REPLICATE(m.g_horiz,57)>><<m.g_corn2>>
  7155. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7156. \*       <<m.g_verti1>>
  7157. \\ <<PADC(m.msg,55," ")>>
  7158. \\ <<m.g_verti2>>
  7159. \*       <<m.g_verti1>><<REPLICATE(" ",57)>><<m.g_verti2>>
  7160. \*       <<m.g_corn3>><<REPLICATE(m.g_horiz,57)>><<m.g_corn4>>
  7161. \*
  7162. \
  7163.  
  7164. *
  7165. * GENCOMMENT - Generate a comment.
  7166. *
  7167. *!*****************************************************************************
  7168. *!
  7169. *!      Procedure: GENCOMMENT
  7170. *!
  7171. *!      Called by: GENVALIDBODY       (procedure in GENSCRN.PRG)
  7172. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  7173. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7174. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7175. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7176. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  7177. *!
  7178. *!*****************************************************************************
  7179. PROCEDURE gencomment
  7180. PARAMETER m.msg
  7181. \*
  7182. \* <<m.msg>>
  7183. \*
  7184.  
  7185. **
  7186. ** General Supporting Routines
  7187. **
  7188.  
  7189. *
  7190. * BASENAME - returns strippath(stripext(filespec))
  7191. *
  7192. *!*****************************************************************************
  7193. *!
  7194. *!       Function: BASENAME
  7195. *!
  7196. *!      Called by: PREPSCREENS()      (function  in GENSCRN.PRG)
  7197. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  7198. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  7199. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7200. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7201. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7202. *!               : GENRELSTMTS        (procedure in GENSCRN.PRG)
  7203. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  7204. *!               : PROCCOMMENTBLOCK   (procedure in GENSCRN.PRG)
  7205. *!
  7206. *!          Calls: STRIPPATH()        (function  in GENSCRN.PRG)
  7207. *!               : STRIPEXT()         (function  in GENSCRN.PRG)
  7208. *!
  7209. *!*****************************************************************************
  7210. FUNCTION basename
  7211. PARAMETER m.filename
  7212. RETURN strippath(stripext(m.filename))
  7213.  
  7214. *
  7215. * STRIPEXT - Strip the extension from a file name.
  7216. *
  7217. * Description:
  7218. * Use the algorithm employed by FoxPRO itself to strip a
  7219. * file of an extension (if any): Find the rightmost dot in
  7220. * the filename.  If this dot occurs to the right of a "\"
  7221. * or ":", then treat everything from the dot rightward
  7222. * as an extension.  Of course, if we found no dot,
  7223. * we just hand back the filename unchanged.
  7224. *
  7225. * Parameters:
  7226. * filename - character string representing a file name
  7227. *
  7228. * Return value:
  7229. * The string "filename" with any extension removed
  7230. *
  7231. *!*****************************************************************************
  7232. *!
  7233. *!       Function: STRIPEXT
  7234. *!
  7235. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  7236. *!               : BASENAME()         (function  in GENSCRN.PRG)
  7237. *!
  7238. *!*****************************************************************************
  7239. FUNCTION stripext
  7240. PARAMETER m.filename
  7241. PRIVATE m.dotpos, m.terminator
  7242. m.dotpos = RAT(".", m.filename)
  7243. m.terminator = MAX(RAT("\", m.filename), RAT(":", m.filename))
  7244. IF m.dotpos > m.terminator
  7245.    m.filename = LEFT(m.filename, m.dotpos-1)
  7246. ENDIF
  7247. RETURN m.filename
  7248.  
  7249. *
  7250. * STRIPPATH - Strip the path from a file name.
  7251. *
  7252. * Description:
  7253. * Find positions of backslash in the name of the file.  If there is one
  7254. * take everything to the right of its position and make it the new file
  7255. * name.  If there is no slash look for colon.  Again if found, take
  7256. * everything to the right of it as the new name.  If neither slash
  7257. * nor colon are found then return the name unchanged.
  7258. *
  7259. * Parameters:
  7260. * filename - character string representing a file name
  7261. *
  7262. * Return value:
  7263. * The string "filename" with any path removed
  7264. *
  7265. *!*****************************************************************************
  7266. *!
  7267. *!       Function: STRIPPATH
  7268. *!
  7269. *!      Called by: GENOPENDBFS        (procedure in GENSCRN.PRG)
  7270. *!               : BASENAME()         (function  in GENSCRN.PRG)
  7271. *!
  7272. *!*****************************************************************************
  7273. FUNCTION strippath
  7274. PARAMETER m.filename
  7275. PRIVATE m.slashpos, m.namelen, m.colonpos
  7276. m.slashpos = RAT("\", m.filename)
  7277. IF m.slashpos > 0
  7278.    m.namelen  = LEN(m.filename) - m.slashpos
  7279.    m.filename = RIGHT(m.filename, m.namelen)
  7280. ELSE
  7281.    m.colonpos = RAT(":", m.filename)
  7282.    IF m.colonpos > 0
  7283.       m.namelen  = LEN(m.filename) - m.colonpos
  7284.       m.filename = RIGHT(m.filename, m.namelen)
  7285.    ENDIF
  7286. ENDIF
  7287. RETURN m.filename
  7288.  
  7289. *
  7290. * STRIPCR - Strip off terminating carriage returns and line feeds
  7291. *
  7292. *!*****************************************************************************
  7293. *!
  7294. *!       Function: STRIPCR
  7295. *!
  7296. *!*****************************************************************************
  7297. FUNCTION stripcr
  7298. PARAMETER m.strg
  7299. * Don't use a CHRTRAN since it's remotely possible that the CR or LF might
  7300. * be in a user's quoted string.
  7301. strg = ALLTRIM(strg)
  7302. i = LEN(strg)
  7303. DO WHILE i >= 0 AND INLIST(SUBSTR(strg,i,1),CHR(13),CHR(10))
  7304.    i = i - 1
  7305. ENDDO
  7306. RETURN LEFT(strg,i)
  7307.  
  7308. *
  7309. * ADDBS - Add a backslash unless there is one already there.
  7310. *
  7311. *!*****************************************************************************
  7312. *!
  7313. *!       Function: ADDBS
  7314. *!
  7315. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7316. *!
  7317. *!*****************************************************************************
  7318. FUNCTION addbs
  7319. * Add a backslash to a path name, if there isn't already one there
  7320. PARAMETER m.pathname
  7321. PRIVATE ALL
  7322. m.pathname = ALLTRIM(UPPER(m.pathname))
  7323. IF !(RIGHT(m.pathname,1) $ '\:') AND !EMPTY(m.pathname)
  7324.    m.pathname = m.pathname + '\'
  7325. ENDIF
  7326. RETURN m.pathname
  7327.  
  7328. *
  7329. * JUSTFNAME - Return just the filename (i.e., no path) from "filname"
  7330. *
  7331. *!*****************************************************************************
  7332. *!
  7333. *!       Function: JUSTFNAME
  7334. *!
  7335. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7336. *!
  7337. *!*****************************************************************************
  7338. FUNCTION justfname
  7339. PARAMETERS m.filname
  7340. PRIVATE ALL
  7341. IF RAT('\',m.filname) > 0
  7342.    m.filname = SUBSTR(m.filname,RAT('\',m.filname)+1,255)
  7343. ENDIF
  7344. IF AT(':',m.filname) > 0
  7345.    m.filname = SUBSTR(m.filname,AT(':',m.filname)+1,255)
  7346. ENDIF
  7347. RETURN ALLTRIM(UPPER(m.filname))
  7348.  
  7349. *
  7350. * JUSTPATH - Returns just the pathname.
  7351. *
  7352. *!*****************************************************************************
  7353. *!
  7354. *!       Function: JUSTPATH
  7355. *!
  7356. *!      Called by: FORCEEXT()         (function  in GENSCRN.PRG)
  7357. *!
  7358. *!*****************************************************************************
  7359. FUNCTION justpath
  7360. * Return just the path name from "filname"
  7361. PARAMETERS m.filname
  7362. PRIVATE ALL
  7363. m.filname = ALLTRIM(UPPER(m.filname))
  7364. IF '\' $ m.filname
  7365.    m.filname = SUBSTR(m.filname,1,RAT('\',m.filname))
  7366.    IF RIGHT(m.filname,1) = '\' AND LEN(m.filname) > 1 ;
  7367.          AND SUBSTR(m.filname,LEN(m.filname)-1,1) <> ':'
  7368.       m.filname = SUBSTR(m.filname,1,LEN(m.filname)-1)
  7369.    ENDIF
  7370.    RETURN m.filname
  7371. ELSE
  7372.    RETURN ''
  7373. ENDIF
  7374.  
  7375. *
  7376. * FORCEEXT - Force filename to have a paricular extension.
  7377. *
  7378. *!*****************************************************************************
  7379. *!
  7380. *!       Function: FORCEEXT
  7381. *!
  7382. *!          Calls: JUSTPATH()         (function  in GENSCRN.PRG)
  7383. *!               : JUSTFNAME()        (function  in GENSCRN.PRG)
  7384. *!               : ADDBS()            (function  in GENSCRN.PRG)
  7385. *!
  7386. *!*****************************************************************************
  7387. FUNCTION forceext
  7388. * Force the extension of "filname" to be whatever ext is.
  7389. PARAMETERS m.filname,m.ext
  7390. PRIVATE ALL
  7391. IF SUBSTR(m.ext,1,1) = "."
  7392.    m.ext = SUBSTR(m.ext,2,3)
  7393. ENDIF
  7394.  
  7395. m.pname = justpath(m.filname)
  7396. m.filname = justfname(UPPER(ALLTRIM(m.filname)))
  7397. IF AT('.',m.filname) > 0
  7398.    m.filname = SUBSTR(m.filname,1,AT('.',m.filname)-1) + '.' + m.ext
  7399. ELSE
  7400.    m.filname = m.filname + '.' + m.ext
  7401. ENDIF
  7402. RETURN addbs(m.pname) + m.filname
  7403.  
  7404. *
  7405. * WhatStyle - Return the style string which corresponds to the style
  7406. *                   stored in screen database.
  7407. *
  7408. *!*****************************************************************************
  7409. *!
  7410. *!       Function: WHATSTYLE
  7411. *!
  7412. *!*****************************************************************************
  7413. FUNCTION whatstyle
  7414. PARAMETER m.stylenum
  7415. IF NOT EMPTY(m.stylenum)
  7416.    DO CASE
  7417.    CASE m.stylenum= 1
  7418.       RETURN "B"
  7419.    CASE m.stylenum= 2
  7420.       RETURN "I"
  7421.    OTHERWISE
  7422.       RETURN "BI"
  7423.    ENDCASE
  7424. ELSE
  7425.    RETURN ""
  7426. ENDIF
  7427.  
  7428. *
  7429. * UNIQUEWIN - Check if a window name is unique.
  7430. *
  7431. *!*****************************************************************************
  7432. *!
  7433. *!       Function: UNIQUEWIN
  7434. *!
  7435. *!      Called by: GENWINDEFI         (procedure in GENSCRN.PRG)
  7436. *!
  7437. *!*****************************************************************************
  7438. FUNCTION uniquewin
  7439. PARAMETER m.windowname, m.windcnt, m.arry
  7440. EXTERNAL ARRAY arry
  7441. PRIVATE m.found, m.i, m.first, m.middle
  7442. m.found  = .F.
  7443. m.first  = 1
  7444. m.last   = m.windcnt
  7445. m.middle = 0
  7446.  
  7447. IF EMPTY(arry[1,1])
  7448.    RETURN 1
  7449. ENDIF
  7450. DO WHILE (m.last >= m.first) AND NOT m.found
  7451.    m.middle = INT((m.first+m.last) / 2)
  7452.    DO CASE
  7453.    CASE m.windowname < arry[m.middle,1]
  7454.       m.last = m.middle - 1
  7455.    CASE m.windowname > arry[m.middle,1]
  7456.       m.first = m.middle + 1
  7457.    OTHERWISE
  7458.       m.found = .T.
  7459.    ENDCASE
  7460. ENDDO
  7461. IF m.found
  7462.    RETURN 0
  7463. ELSE
  7464.    RETURN m.first
  7465. ENDIF
  7466.  
  7467. *
  7468. * ADDTOCTRL - Generate clause code for object level cluses.
  7469. *
  7470. *!*****************************************************************************
  7471. *!
  7472. *!      Procedure: ADDTOCTRL
  7473. *!
  7474. *!      Called by: ELEMRANGE          (procedure in GENSCRN.PRG)
  7475. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  7476. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  7477. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  7478. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  7479. *!
  7480. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  7481. *!               : GENFUNCHEADER      (procedure in GENSCRN.PRG)
  7482. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  7483. *!               : ATWNAME()          (function  in GENSCRN.PRG)
  7484. *!               : ISCOMMENT()        (function  in GENSCRN.PRG)
  7485. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  7486. *!
  7487. *!*****************************************************************************
  7488. PROCEDURE addtoctrl
  7489. PARAMETER m.procname, m.from, m.memo, m.varname
  7490. PRIVATE m.linecnt, m.count, m.textline, m.genfunction, m.notcomnt, m.at, ;
  7491.    m.thispretext, m.in_dec, m.platnum, m.wnamelen, m.upline, m.thisplat
  7492.  
  7493. m.thisplat = IIF(TYPE("platform") <> "U",platform,"DOS")
  7494. m.platnum = getplatnum(m.thisplat)
  7495.  
  7496. * Write this clause to the temporary file
  7497. _TEXT = m.g_tmphandle
  7498. m.thispretext = _PRETEXT
  7499. _PRETEXT = ""
  7500.  
  7501. m.genfunction = .F.
  7502. m.notcomnt = 0
  7503. m.linecnt = MEMLINES(m.memo)
  7504. _MLINE = 0
  7505. DO genfuncheader WITH m.procname, m.from, .F., ALLTRIM(m.varname)
  7506. FOR m.count = 1 TO m.linecnt
  7507.    m.textline = MLINE(m.memo, 1, _MLINE)
  7508.    m.upline = UPPER(LTRIM(CHRTRAN(m.textline,chr(9),' ')))
  7509.    IF oktogenerate(m.textline, @notcomnt)
  7510.       IF m.notcomnt > 0 AND NOT m.genfunction
  7511.          \FUNCTION <<m.procname>>     &&  <<m.varname>> <<m.from>>
  7512.          in_dec = SET("DECIMALS")
  7513.          SET DECIMALS TO 0
  7514.          \#REGION <<INT(m.g_screen)>>
  7515.          SET DECIMALS TO in_dec
  7516.          m.genfunction = .T.
  7517.       ENDIF
  7518.  
  7519.       IF NOT EMPTY(g_wnames[m.g_screen, m.platnum])
  7520.          m.at = atwname(g_wnames[m.g_screen, m.platnum], m.textline)
  7521.          IF m.at <> 0 AND !iscomment(@textline)
  7522.             m.wnamelen = LEN(g_wnames[m.g_screen, m.platnum])
  7523.             \<<STUFF(m.textline, m.at, m.wnamelen,g_screens[m.g_screen,2])>>
  7524.             *\<<m.textline>>
  7525.          ELSE
  7526.             IF !geninsertcode(@upline,m.g_screen, .F., m.thisplat)
  7527.                \<<m.textline>>
  7528.             ENDIF
  7529.          ENDIF
  7530.       ELSE
  7531.          IF !geninsertcode(@upline,m.g_screen, .F., m.thisplat)
  7532.             \<<m.textline>>
  7533.          ENDIF
  7534.       ENDIF
  7535.    ENDIF
  7536. ENDFOR
  7537. IF m.notcomnt = 0
  7538.    \FUNCTION <<m.procname>>     &&  <<m.varname>> <<m.from>>
  7539. ENDIF
  7540. _TEXT = m.g_orghandle
  7541. _PRETEXT = m.thispretext
  7542.  
  7543. *
  7544. * OKTOGENERATE - Ok to generate this line?
  7545. *
  7546. * Description:
  7547. * Check if the code segment provided by the user for the object level
  7548. * VALID, MESSAGE, and WHEN clauses does not contain 'FUNCTION',
  7549. * 'PROCEDURE' or 'PARAMETER' statements as its first non-comment
  7550. * statements.  Further, do not output #NAME directives. This is done on line by
  7551. * line basis.
  7552. *
  7553. *!*****************************************************************************
  7554. *!
  7555. *!       Function: OKTOGENERATE
  7556. *!
  7557. *!      Called by: ADDTOCTRL          (procedure in GENSCRN.PRG)
  7558. *!
  7559. *!          Calls: WORDNUM()          (function  in GENSCRN.PRG)
  7560. *!               : MATCH()            (function  in GENSCRN.PRG)
  7561. *!
  7562. *!*****************************************************************************
  7563. FUNCTION oktogenerate
  7564. PARAMETER m.text, m.notcomnt
  7565. * "notcomnt" needs to be passed by reference, and is changed in this module
  7566.  
  7567. PRIVATE m.asterisk, m.ampersand, m.isnote, m.name, m.statement, m.word1
  7568. IF EMPTY(m.text)
  7569.    RETURN .T.
  7570. ENDIF
  7571.  
  7572. m.statement = UPPER(LTRIM(m.text))
  7573.  
  7574. DO CASE
  7575. CASE AT("*", m.statement) = 1 ;
  7576.       OR AT(m.g_dblampersand, m.statement) = 1 ;
  7577.       OR AT("NOTE", m.statement) = 1
  7578.    RETURN .T.
  7579. OTHERWISE
  7580.    * OK, it's not a comment
  7581.    m.notcomnt = m.notcomnt + 1
  7582.    * Make a quick test to see if we may exclude this line
  7583.    IF AT(LEFT(statement,1),"PF#") > 0
  7584.       * Postpone the expensive wordnum and match functions as long as possible
  7585.       word1 = CHRTRAN(wordnum(statement,1),';','')
  7586.       DO CASE
  7587.       CASE match(word1,"PROCEDURE") OR match(word1,"FUNCTION") OR match(word1,"PARAMETERS")
  7588.          *
  7589.          * If the first non-comment line is a FUNCTION, PROCEDURE, or
  7590.          * a PARAMETER statement then do not generate it.
  7591.          *
  7592.          IF m.notcomnt = 1
  7593.             RETURN .F.
  7594.          ENDIF
  7595.       CASE LEFT(statement,5) == "#NAME"   && Don't ever emit a #NAME directive
  7596.          RETURN .F.
  7597.       ENDCASE
  7598.    ENDIF
  7599. ENDCASE
  7600. RETURN .T.
  7601.  
  7602. *
  7603. * OBJECT - Return name of an object.
  7604. *
  7605. *!*****************************************************************************
  7606. *!
  7607. *!       Function: OBJECT
  7608. *!
  7609. *!*****************************************************************************
  7610. FUNCTION OBJECT
  7611. PARAMETER m.objecttype
  7612. PRIVATE m.objname
  7613. DO CASE
  7614. CASE m.objecttype = 11
  7615.    m.objname = "List"
  7616. CASE m.objecttype = 12
  7617.    m.objname = "Push Button"
  7618. CASE m.objecttype = 13
  7619.    m.objname = "Radio Button"
  7620. CASE m.objecttype = 14
  7621.    m.objname = "Check Box"
  7622. CASE m.objecttype = 15
  7623.    m.objname = "Field"
  7624. CASE m.objecttype = 16
  7625.    m.objname = "Popup"
  7626. OTHERWISE
  7627.    m.objname = ""
  7628. ENDCASE
  7629. RETURN m.objname
  7630.  
  7631. *
  7632. * COMBINE - Combine the original and the temp files.
  7633. *
  7634. *!*****************************************************************************
  7635. *!
  7636. *!      Procedure: COMBINE
  7637. *!
  7638. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7639. *!
  7640. *!          Calls: ERRORHANDLER       (procedure in GENSCRN.PRG)
  7641. *!
  7642. *!*****************************************************************************
  7643. PROCEDURE combine
  7644. PRIVATE m.size, m.top, m.end, m.status, m.chunk
  7645.  
  7646. IF m.g_graphic
  7647.    SET MESSAGE TO 'Merging Files'
  7648. ENDIF
  7649. m.size = FSEEK(m.g_tmphandle,0,2)
  7650. m.top  = FSEEK(m.g_tmphandle,0)
  7651.  
  7652. DO WHILE .T.
  7653.    m.chunk = IIF(m.size>65000, 65000, m.size)
  7654.    m.end   = FSEEK(m.g_orghandle,0,2)
  7655.    m.status = FWRITE(m.g_orghandle,FREAD(m.g_tmphandle,m.chunk))
  7656.    IF m.status = 0 AND m.size > 0
  7657.       DO errorhandler WITH "Unsuccessful file merge...",;
  7658.          LINENO(), c_error_2
  7659.    ENDIF
  7660.    m.size = m.size - 65000
  7661.    IF m.size < 0
  7662.       EXIT
  7663.    ENDIF
  7664. ENDDO
  7665. IF m.g_graphic
  7666.    SET MESSAGE TO 'Generation Complete'
  7667. ELSE
  7668.    WAIT CLEAR
  7669. ENDIF
  7670. RETURN
  7671.  
  7672. **
  7673. ** Code Associated With Displaying of the Thermometer
  7674. **
  7675.  
  7676. *
  7677. * ACTTHERM(<text>) - Activate thermometer.
  7678. *
  7679. * Activates thermometer.  Update the thermometer with UPDTHERM().
  7680. * Thermometer window is named "thermometer."  Be sure to RELEASE
  7681. * this window when done with thermometer.  Creates the global
  7682. * m.g_thermwidth.
  7683. *
  7684. *!*****************************************************************************
  7685. *!
  7686. *!      Procedure: ACTTHERM
  7687. *!
  7688. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7689. *!
  7690. *!*****************************************************************************
  7691. PROCEDURE acttherm
  7692. PARAMETER m.text
  7693. PRIVATE m.prompt
  7694.  
  7695. IF m.g_graphic
  7696.    m.prompt = LOWER(m.g_outfile)
  7697.    IF TXTWIDTH(m.prompt, c_dlgface, c_dlgsize, c_dlgstyle) > 43
  7698.       DO WHILE TXTWIDTH(m.prompt+"...", c_dlgface, c_dlgsize, c_dlgstyle) > 43
  7699.          m.prompt = LEFT(m.prompt, LEN(m.prompt)-1)
  7700.       ENDDO
  7701.       m.prompt = m.prompt + "..."
  7702.    ENDIF
  7703.  
  7704.    DEFINE WINDOW thermomete ;
  7705.       AT  INT((SROW() - (( 5.615 * ;
  7706.       FONTMETRIC(1, c_dlgface, c_dlgsize, c_dlgstyle )) / ;
  7707.       FONTMETRIC(1, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2), ;
  7708.       INT((SCOL() - (( 63.833 * ;
  7709.       FONTMETRIC(6, c_dlgface, c_dlgsize, c_dlgstyle )) / ;
  7710.       FONTMETRIC(6, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2) ;
  7711.       SIZE 5.615,63.833 ;
  7712.       FONT c_dlgface, c_dlgsize ;
  7713.       STYLE c_dlgstyle ;
  7714.       NOFLOAT ;
  7715.       NOCLOSE ;
  7716.       NONE ;
  7717.       COLOR RGB(0, 0, 0, 192, 192, 192)
  7718.    MOVE WINDOW thermomete CENTER
  7719.    ACTIVATE WINDOW thermomete NOSHOW
  7720.  
  7721.    @ 0.5,3 SAY m.text FONT c_dlgface, c_dlgsize STYLE c_dlgstyle
  7722.    @ 1.5,3 SAY m.prompt FONT c_dlgface, c_dlgsize STYLE c_dlgstyle
  7723.    @ 0.000,0.000 TO 0.000,63.833 ;
  7724.       COLOR RGB(255, 255, 255, 255, 255, 255)
  7725.    @ 0.000,0.000 TO 5.615,0.000 ;
  7726.       COLOR RGB(255, 255, 255, 255, 255, 255)
  7727.    @ 0.385,0.667 TO 5.231,0.667 ;
  7728.       COLOR RGB(128, 128, 128, 128, 128, 128)
  7729.    @ 0.308,0.667 TO 0.308,63.167 ;
  7730.       COLOR RGB(128, 128, 128, 128, 128, 128)
  7731.    @ 0.385,63.000 TO 5.308,63.000 ;
  7732.       COLOR RGB(255, 255, 255, 255, 255, 255)
  7733.    @ 5.231,0.667 TO 5.231,63.167 ;
  7734.       COLOR RGB(255, 255, 255, 255, 255, 255)
  7735.    @ 5.538,0.000 TO 5.538,63.833 ;
  7736.       COLOR RGB(128, 128, 128, 128, 128, 128)
  7737.    @ 0.000,63.667 TO 5.615,63.667 ;
  7738.       COLOR RGB(128, 128, 128, 128, 128, 128)
  7739.    @ 3.000,3.333 TO 4.231,3.333 ;
  7740.       COLOR RGB(128, 128, 128, 128, 128, 128)
  7741.    @ 3.000,60.333 TO 4.308,60.333 ;
  7742.       COLOR RGB(255, 255, 255, 255, 255, 255)
  7743.    @ 3.000,3.333 TO 3.000,60.333 ;
  7744.       COLOR RGB(128, 128, 128, 128, 128, 128)
  7745.    @ 4.231,3.333 TO 4.231,60.500 ;
  7746.       COLOR RGB(255, 255, 255, 255, 255, 255)
  7747.    m.g_thermwidth = 56.269
  7748.  
  7749.    SHOW WINDOW thermomete TOP
  7750. ELSE
  7751.    m.prompt = SUBSTR(SYS(2014,m.g_outfile),1,48)+;
  7752.       IIF(LEN(m.g_outfile)>48,"...","")
  7753.  
  7754.    DEFINE WINDOW thermomete;
  7755.       FROM INT((SROW()-6)/2), INT((SCOL()-57)/2) ;
  7756.       TO INT((SROW()-6)/2) + 6, INT((SCOL()-57)/2) + 57;
  7757.       DOUBLE COLOR SCHEME 5
  7758.    ACTIVATE WINDOW thermomete NOSHOW
  7759.  
  7760.    m.g_thermwidth = 50
  7761.    @ 0,3 SAY m.text
  7762.    @ 1,3 SAY UPPER(m.prompt)
  7763.    @ 2,1 TO 4,m.g_thermwidth+4 &g_boxstrg
  7764.  
  7765.    SHOW WINDOW thermomete TOP
  7766. ENDIF
  7767. RETURN
  7768.  
  7769. *
  7770. * UPDTHERM(<percent>) - Update thermometer.
  7771. *
  7772. *!*****************************************************************************
  7773. *!
  7774. *!      Procedure: UPDTHERM
  7775. *!
  7776. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7777. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  7778. *!               : BUILDCTRL          (procedure in GENSCRN.PRG)
  7779. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  7780. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  7781. *!
  7782. *!*****************************************************************************
  7783. PROCEDURE updtherm
  7784. PARAMETER m.percent
  7785. PRIVATE m.nblocks, m.percent
  7786.  
  7787. ACTIVATE WINDOW thermomete
  7788.  
  7789. * Map to the number of platforms we are generating for
  7790. m.percent = MIN(INT(m.percent / m.g_numplatforms) ,100)
  7791.  
  7792. m.nblocks = (m.percent/100) * (m.g_thermwidth)
  7793. IF m.g_graphic
  7794.    @ 3.000,3.333 TO 4.231,m.nblocks + 3.333 ;
  7795.       PATTERN 1 COLOR RGB(128, 128, 128, 128, 128, 128)
  7796. ELSE
  7797.  
  7798. * CGC MMM               1994.2.21
  7799. *   @ 3,3 SAY REPLICATE("█",m.nblocks)
  7800.    @ 3,3 SAY REPLICATE("ä",m.nblocks)
  7801. * CGC MMM
  7802.  
  7803. ENDIF
  7804. RETURN
  7805.  
  7806. *
  7807. * DEACTTHERMO - Deactivate and Release thermometer window.
  7808. *
  7809. *!*****************************************************************************
  7810. *!
  7811. *!      Procedure: DEACTTHERMO
  7812. *!
  7813. *!      Called by: BUILD              (procedure in GENSCRN.PRG)
  7814. *!
  7815. *!*****************************************************************************
  7816. PROCEDURE deactthermo
  7817. IF WEXIST("thermomete")
  7818.    RELEASE WINDOW thermomete
  7819. ENDIF
  7820. RETURN
  7821.  
  7822. **
  7823. ** Error Handling Code
  7824. **
  7825.  
  7826. *
  7827. * ERRORHANDLER - Error Processing Center.
  7828. *
  7829. *!*****************************************************************************
  7830. *!
  7831. *!      Procedure: ERRORHANDLER
  7832. *!
  7833. *!      Called by: GENSCRN.PRG
  7834. *!               : OPENPROJDBF()      (function  in GENSCRN.PRG)
  7835. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  7836. *!               : CHECKPARAM()       (function  in GENSCRN.PRG)
  7837. *!               : PREPFILE           (procedure in GENSCRN.PRG)
  7838. *!               : CLOSEFILE          (procedure in GENSCRN.PRG)
  7839. *!               : GETPLATFORM()      (function  in GENSCRN.PRG)
  7840. *!               : REFRESHPREFS       (procedure in GENSCRN.PRG)
  7841. *!               : DISPATCHBUILD      (procedure in GENSCRN.PRG)
  7842. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  7843. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  7844. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  7845. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  7846. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  7847. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  7848. *!               : GENOPENDBFS        (procedure in GENSCRN.PRG)
  7849. *!               : DOPLACECLAUSE      (procedure in GENSCRN.PRG)
  7850. *!               : FINDREADCLAUSES    (procedure in GENSCRN.PRG)
  7851. *!               : COMBINE            (procedure in GENSCRN.PRG)
  7852. *!
  7853. *!          Calls: CLEANUP            (procedure in GENSCRN.PRG)
  7854. *!               : ERRLOG             (procedure in GENSCRN.PRG)
  7855. *!               : ERRSHOW            (procedure in GENSCRN.PRG)
  7856. *!               : CLOSEFILE          (procedure in GENSCRN.PRG)
  7857. *!
  7858. *!*****************************************************************************
  7859. PROCEDURE errorhandler
  7860. PARAMETERS m.msg, m.linenum, m.errcode
  7861. IF ERROR() = 22   && too many memory variables--just bomb out as fast as we can
  7862.    ON ERROR
  7863.    DO cleanup
  7864.    CANCEL
  7865. ENDIF
  7866.  
  7867. DO CASE
  7868. CASE errcode == "Minor"
  7869.    DO errlog WITH m.msg, m.linenum
  7870.    m.g_status = 1
  7871. CASE errcode == "Serious"
  7872.    DO errlog  WITH m.msg, m.linenum
  7873.    DO errshow WITH m.msg, m.linenum
  7874.    m.g_status = 2
  7875.    ON ERROR
  7876. CASE errcode == "Fatal"
  7877.    ON ERROR
  7878.    IF m.g_havehand = .T.
  7879.       DO errlog WITH m.msg, m.linenum
  7880.       DO closefile WITH m.g_orghandle
  7881.       DO closefile WITH m.g_tmphandle
  7882.    ENDIF
  7883.    DO errshow WITH m.msg, m.linenum
  7884.    IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  7885.       RELEASE WINDOW thermometer
  7886.    ENDIF
  7887.    DO cleanup
  7888.    CANCEL
  7889. ENDCASE
  7890.  
  7891. *
  7892. * ESCHANDLER - Escape handler.
  7893. *
  7894. *!*****************************************************************************
  7895. *!
  7896. *!      Procedure: ESCHANDLER
  7897. *!
  7898. *!      Called by: BUILDENABLE        (procedure in GENSCRN.PRG)
  7899. *!
  7900. *!          Calls: BUILDDISABLE       (procedure in GENSCRN.PRG)
  7901. *!               : CLEANUP            (procedure in GENSCRN.PRG)
  7902. *!
  7903. *!*****************************************************************************
  7904. PROCEDURE eschandler
  7905. ON ERROR
  7906. WAIT WINDOW "Generation process stopped." NOWAIT
  7907. DO builddisable
  7908. IF m.g_havehand
  7909.    ERASE (m.g_outfile)
  7910.    ERASE (m.g_tmpfile)
  7911. ENDIF
  7912. IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  7913.    RELEASE WINDOW thermometer
  7914. ENDIF
  7915. DO cleanup
  7916. CANCEL
  7917.  
  7918. *
  7919. * ERRLOG - Save an error message in the error log file.
  7920. *
  7921. *!*****************************************************************************
  7922. *!
  7923. *!      Procedure: ERRLOG
  7924. *!
  7925. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  7926. *!
  7927. *!          Calls: OPENERRFILE        (procedure in GENSCRN.PRG)
  7928. *!
  7929. *!*****************************************************************************
  7930. PROCEDURE errlog
  7931. PARAMETER m.msg, m.linenum
  7932. DO openerrfile
  7933.  
  7934. SET CONSOLE OFF
  7935. \\GENERATOR: <<ALLTRIM(m.msg)>>
  7936. IF NOT EMPTY(m.linenum)
  7937.    \\ LINE NUMBER: <<m.linenum>>
  7938. ENDIF
  7939. \
  7940. = FCLOSE(_TEXT)
  7941. _TEXT = m.g_orghandle
  7942.  
  7943. *
  7944. * ERRSHOW - Show error in an alert box on the screen.
  7945. *
  7946. *!*****************************************************************************
  7947. *!
  7948. *!      Procedure: ERRSHOW
  7949. *!
  7950. *!      Called by: ERRORHANDLER       (procedure in GENSCRN.PRG)
  7951. *!               : OPENERRFILE        (procedure in GENSCRN.PRG)
  7952. *!
  7953. *!*****************************************************************************
  7954. PROCEDURE errshow
  7955. PARAMETER m.msg, m.lineno
  7956. PRIVATE m.curcursor
  7957.  
  7958. IF m.g_graphic
  7959.    DEFINE WINDOW ALERT ;
  7960.       AT  INT((SROW() - (( 6.615 * ;
  7961.       FONTMETRIC(1, c_dlgface, c_dlgsize, c_dlgstyle )) / ;
  7962.       FONTMETRIC(1, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2), ;
  7963.       INT((SCOL() - (( 63.833 * ;
  7964.       FONTMETRIC(6, c_dlgface, c_dlgsize, c_dlgstyle )) / ;
  7965.       FONTMETRIC(6, WFONT(1,""), WFONT(2,""), WFONT(3,"")))) / 2) ;
  7966.       SIZE 6.615,63.833 ;
  7967.       FONT c_dlgface, c_dlgsize ;
  7968.       STYLE c_dlgstyle ;
  7969.       NOCLOSE ;
  7970.       DOUBLE ;
  7971.       TITLE "Genscrn Error" ;
  7972.       COLOR RGB(0, 0, 0, 255, 255, 255)
  7973.    MOVE WINDOW ALERT CENTER
  7974.    ACTIVATE WINDOW ALERT NOSHOW
  7975.  
  7976.    m.dispmsg = m.msg
  7977.    IF TXTWIDTH(m.dispmsg) > WCOLS()
  7978.       * Make sure it isn't too long.
  7979.       DO WHILE TXTWIDTH(m.dispmsg+'...') > WCOLS()
  7980.          m.dispmsg = LEFT(m.dispmsg,LEN(m.dispmsg)-1)
  7981.       ENDDO
  7982.       IF m.msg <> m.dispmsg    && Has display message been shortened?
  7983.          m.dispmsg = m.dispmsg + '...'
  7984.       ENDIF
  7985.    ENDIF
  7986.  
  7987.    @ 1,MAX((WCOLS()-TXTWIDTH( m.dispmsg ))/2,1) SAY m.dispmsg
  7988.  
  7989.    m.msg = "Genscrn Line Number: "+STR(m.lineno, 4)
  7990.    @ 2,(WCOLS()-TXTWIDTH( m.msg ))/2 SAY m.msg
  7991.  
  7992.    IF TYPE("m.g_screen") <> "U" AND m.g_screen <> 0
  7993.       m.msg = "Generating from: "+LOWER(g_screens[m.g_screen,1])
  7994.       @ 3,MAX((WCOLS()-TXTWIDTH( m.msg ))/2,1) SAY m.msg
  7995.    ENDIF
  7996.  
  7997.    m.msg = "Press any key to cleanup and exit..."
  7998.    @ 4,(WCOLS()-TXTWIDTH( m.msg ))/2 SAY m.msg
  7999.  
  8000.    SHOW WINDOW ALERT
  8001. ELSE
  8002.    DEFINE WINDOW ALERT;
  8003.       FROM INT((SROW()-7)/2), INT((SCOL()-50)/2) TO INT((SROW()-7)/2) + 6, INT((SCOL()-50)/2) + 50 ;
  8004.       FLOAT NOGROW NOCLOSE NOZOOM SHADOW DOUBLE;
  8005.       COLOR SCHEME 7
  8006.  
  8007.    ACTIVATE WINDOW ALERT
  8008.  
  8009.    @ 0,0 CLEAR
  8010.    @ 1,0 SAY PADC(SUBSTR(m.msg,1,44)+;
  8011.       IIF(LEN(m.msg)>44,"...",""), WCOLS())
  8012.    @ 2,0 SAY PADC("Line Number: "+STR(m.lineno, 4), WCOLS())
  8013.  
  8014.    IF TYPE("m.g_screen") <> "U" AND m.g_screen <> 0
  8015.       m.msg = "Working on screen: "+LOWER(g_screens[m.g_screen])
  8016.       @ 3,0 SAY PADC(m.msg,WCOLS())
  8017.    ENDIF
  8018.  
  8019.    @ 4,0 SAY PADC("Press any key to cleanup and exit...", WCOLS())
  8020. ENDIF
  8021.  
  8022. m.curcursor = SET( "CURSOR" )
  8023. SET CURSOR OFF
  8024.  
  8025. WAIT ""
  8026.  
  8027. RELEASE WINDOW ALERT
  8028. SET CURSOR &curcursor
  8029.  
  8030. RELEASE WINDOW ALERT
  8031.  
  8032. *
  8033. * OPENERRFILE - Open error file.
  8034. *
  8035. *!*****************************************************************************
  8036. *!
  8037. *!      Procedure: OPENERRFILE
  8038. *!
  8039. *!      Called by: ERRLOG             (procedure in GENSCRN.PRG)
  8040. *!
  8041. *!          Calls: ERRSHOW            (procedure in GENSCRN.PRG)
  8042. *!
  8043. *!*****************************************************************************
  8044. PROCEDURE openerrfile
  8045. PRIVATE m.errfile, m.errhandle
  8046. m.errfile   = m.g_errlog+".ERR"
  8047. m.errhandle = FOPEN(m.errfile,2)
  8048. IF m.errhandle < 0
  8049.    m.errhandle = FCREATE(m.errfile)
  8050.    IF m.errhandle < 0
  8051.       DO errshow WITH ".ERR could not be opened...", LINENO()
  8052.       m.g_status = 2
  8053.       IF WEXIST("Thermomete") AND WVISIBLE("Thermomete")
  8054.          RELEASE WINDOW thermometer
  8055.       ENDIF
  8056.       ON ERROR
  8057.       RETURN TO MASTER
  8058.    ENDIF
  8059. ELSE
  8060.    = FSEEK(m.errhandle,0,2)
  8061. ENDIF
  8062. IF SET("TEXTMERGE") = "OFF"
  8063.    SET TEXTMERGE ON
  8064. ENDIF
  8065. _TEXT = m.errhandle
  8066.  
  8067. *
  8068. * PUSHINDENT - Add another indentation level
  8069. *
  8070. *!*****************************************************************************
  8071. *!
  8072. *!      Procedure: PUSHINDENT
  8073. *!
  8074. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8075. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  8076. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  8077. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  8078. *!
  8079. *!*****************************************************************************
  8080. PROCEDURE pushindent
  8081. _PRETEXT = CHR(9) + _PRETEXT
  8082.  
  8083. *
  8084. * POPINDENT - Remove one indentation level
  8085. *
  8086. *!*****************************************************************************
  8087. *!
  8088. *!      Procedure: POPINDENT
  8089. *!
  8090. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8091. *!               : EMITBRACKET        (procedure in GENSCRN.PRG)
  8092. *!               : PLACESAYS          (procedure in GENSCRN.PRG)
  8093. *!               : GENWINDEFI         (procedure in GENSCRN.PRG)
  8094. *!
  8095. *!*****************************************************************************
  8096. PROCEDURE popindent
  8097. IF LEFT(_PRETEXT,1) = CHR(9)
  8098.    _PRETEXT = SUBSTR(_PRETEXT,2)
  8099. ENDIF
  8100.  
  8101. *
  8102. * COUNTPLATFORMS - Count the number of platforms in this SCX that are in common across
  8103. *                    all the SCXs in this screen set.
  8104. *
  8105. *!*****************************************************************************
  8106. *!
  8107. *!      Procedure: COUNTPLATFORMS
  8108. *!
  8109. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8110. *!
  8111. *!*****************************************************************************
  8112. PROCEDURE countplatforms
  8113. PRIVATE m.cnt, m.i
  8114. IF TYPE("g_platforms") <> "U"
  8115.    m.cnt = 0
  8116.    FOR m.i = 1 TO ALEN(g_platforms)
  8117.       IF !EMPTY(g_platforms[m.i])
  8118.          m.cnt = m.cnt + 1
  8119.       ENDIF
  8120.    ENDFOR
  8121.    RETURN m.cnt
  8122. ELSE
  8123.    RETURN 0
  8124. ENDIF
  8125.  
  8126. *
  8127. * LOOKUPPLATFORM - Return the n-th platform name
  8128. *
  8129. *!*****************************************************************************
  8130. *!
  8131. *!      Procedure: LOOKUPPLATFORM
  8132. *!
  8133. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8134. *!
  8135. *!*****************************************************************************
  8136. PROCEDURE lookupplatform
  8137. PARAMETER m.n
  8138. IF TYPE("g_platforms") <> "U" AND ALEN(g_platforms) >= m.n ;
  8139.       AND m.n > 0 AND TYPE("g_platforms[m.n]") = "C"
  8140.    RETURN UPPER(g_platforms[m.n])
  8141. ENDIF
  8142. RETURN ""
  8143.  
  8144. *
  8145. * GETPARAM - Return the PARAMETER statement from a setup snippet, if one is there
  8146. *
  8147. *!*****************************************************************************
  8148. *!
  8149. *!       Function: GETPARAM
  8150. *!
  8151. *!      Called by: CHECKPARAM()       (function  in GENSCRN.PRG)
  8152. *!
  8153. *!          Calls: ISCOMMENT()        (function  in GENSCRN.PRG)
  8154. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  8155. *!               : MATCH()            (function  in GENSCRN.PRG)
  8156. *!
  8157. *!*****************************************************************************
  8158. FUNCTION getparam
  8159. PARAMETER m.snipname
  8160. PRIVATE m.i, m.thisparam, m.numlines, m.thisline, m.word1, m.contin
  8161.  
  8162. * Do a quick check to see if we need to search further.
  8163. IF ATC("PARA",&snipname) = 0
  8164.    RETURN ""
  8165. ENDIF
  8166.  
  8167. m.numlines = MEMLINES(&snipname)
  8168. _MLINE = 0
  8169. m.i = 1
  8170. DO WHILE m.i <= m.numlines
  8171.    m.thisline = UPPER(LTRIM(MLINE(&snipname, 1, _MLINE)))
  8172.  
  8173.    * Drop any double-ampersand comment
  8174.    IF AT(m.g_dblampersand,m.thisline) > 0
  8175.       m.thisline = LEFT(m.thisline,AT(m.g_dblampersand,m.thisline)-1)
  8176.    ENDIF
  8177.  
  8178.    IF !EMPTY(m.thisline) AND !iscomment(@thisline)
  8179.       * See if the first non-blank, non-comment, non-directive, non-EXTERNAL
  8180.       * line is a #SECTION 1
  8181.       DO CASE
  8182.       CASE LEFT(m.thisline,5) = "#SECT" AND AT('1',m.thisline) <> 0
  8183.          * Read until we find a #SECTION 2, the end of the snippet or a
  8184.          * PARAMETER statement.
  8185.          DO WHILE m.i <= m.numlines
  8186.             m.thisline = UPPER(LTRIM(MLINE(&snipname, 1, _MLINE)))
  8187.  
  8188.             * Drop any double-ampersand comment
  8189.             IF AT(m.g_dblampersand,m.thisline) > 0
  8190.                m.thisline = LEFT(m.thisline,AT(m.g_dblampersand,m.thisline)-1)
  8191.             ENDIF
  8192.  
  8193.             m.word1 = wordnum(CHRTRAN(m.thisline,CHR(9)+';',''),1)
  8194.             DO CASE
  8195.             CASE match(m.word1,"PARAMETERS")
  8196.  
  8197.                * Replace tabs with spaces
  8198.                m.thisline = LTRIM(CHRTRAN(m.thisline,CHR(9)," "))
  8199.  
  8200.                * Process continuation lines.  Replace tabs in incoming lines with spaces.
  8201.                DO WHILE RIGHT(RTRIM(m.thisline),1) = ';'
  8202.                   m.thisline = m.thisline + ' '+ CHR(13)+CHR(10)+CHR(9)
  8203.                   m.contin = MLINE(&snipname, 1, _MLINE)
  8204.                   m.contin = CHRTRAN(LTRIM(m.contin),CHR(9)," ")
  8205.                   m.thisline = m.thisline + UPPER(m.contin)
  8206.                ENDDO
  8207.  
  8208.                * Clean up the parameters so that minor differences in
  8209.                * spacing don't cause the comparisons to fail.
  8210.  
  8211.                * Take the parameters but not the PARAMETER keyword itself
  8212.                m.thisparam = SUBSTR(m.thisline,AT(' ',m.thisline)+1)
  8213.                DO WHILE INLIST(LEFT(m.thisparam,1),CHR(10),CHR(13),CHR(9),' ')
  8214.                   m.thisparam = SUBSTR(m.thisparam,2)
  8215.                ENDDO
  8216.  
  8217.                * Force single spacing in the param string
  8218.                DO WHILE AT('  ',m.thisparam) > 0
  8219.                   m.thisparam = STRTRAN(m.thisparam,'  ',' ')
  8220.                ENDDO
  8221.  
  8222.                * Drop "m." designations so that they don't make the variables look different
  8223.                m.thisparam = STRTRAN(m.thisparam,'m.','')
  8224.                m.thisparam = STRTRAN(m.thisparam,'m->','')
  8225.  
  8226.                RETURN LOWER(m.thisparam)
  8227.             CASE LEFT(m.thisline,5) = "#SECT" AND AT('2',m.thisline) <> 0
  8228.                * No parameter statement, since we found #SECTION 2 first
  8229.                RETURN ""
  8230.             ENDCASE
  8231.             m.i = m.i + 1
  8232.          ENDDO
  8233.       CASE LEFT(m.thisline,1) = "#"   && some other directive
  8234.          * Do nothing.  Get next line.
  8235.       CASE match(wordnum(m.thisline,1),"EXTERNAL")
  8236.          * Ignore it.  This doesn't disqualify a later statement from being a PARAMETER
  8237.          * statement.
  8238.       OTHERWISE
  8239.          * no #SECTION 1, so no parameters
  8240.          RETURN ""
  8241.       ENDCASE
  8242.    ENDIF
  8243.    m.i = m.i + 1
  8244. ENDDO
  8245. RETURN ""
  8246.  
  8247.  
  8248. *
  8249. * MATCH - Returns TRUE is candidate is a valid 4-or-more-character abbreviation of keyword
  8250. *
  8251. *!*****************************************************************************
  8252. *!
  8253. *!       Function: MATCH
  8254. *!
  8255. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8256. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  8257. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  8258. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  8259. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8260. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  8261. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  8262. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  8263. *!
  8264. *!*****************************************************************************
  8265. FUNCTION match
  8266. PARAMETER m.candidate, m.keyword
  8267. PRIVATE m.in_exact, m.retlog
  8268.  
  8269. m.in_exact = SET("EXACT")
  8270. SET EXACT OFF
  8271. DO CASE
  8272. CASE EMPTY(m.candidate)
  8273.    m.retlog = EMPTY(m.keyword)
  8274. CASE LEN(m.candidate) < 4
  8275.    m.retlog = IIF(m.candidate == m.keyword,.T.,.F.)
  8276. OTHERWISE
  8277.    m.retlog = IIF(m.keyword = m.candidate,.T.,.F.)
  8278. ENDCASE
  8279. IF m.in_exact != "OFF"
  8280.    SET EXACT ON
  8281. ENDIF
  8282.  
  8283. RETURN m.retlog
  8284.  
  8285. *
  8286. * WORDNUM - Returns w_num-th word from string strg
  8287. *
  8288. *!*****************************************************************************
  8289. *!
  8290. *!       Function: WORDNUM
  8291. *!
  8292. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8293. *!               : EMITPROC           (procedure in GENSCRN.PRG)
  8294. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  8295. *!               : GETFIRSTPROC()     (function  in GENSCRN.PRG)
  8296. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8297. *!               : GENINSERTCODE      (procedure in GENSCRN.PRG)
  8298. *!               : ISPARAMETER()      (function  in GENSCRN.PRG)
  8299. *!               : OKTOGENERATE()     (function  in GENSCRN.PRG)
  8300. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  8301. *!
  8302. *!*****************************************************************************
  8303. FUNCTION wordnum
  8304. PARAMETERS m.strg,m.w_num
  8305. PRIVATE strg,s1,w_num,ret_str
  8306.  
  8307. m.s1 = ALLTRIM(m.strg)
  8308.  
  8309. * Replace tabs with spaces
  8310. m.s1 = CHRTRAN(m.s1,CHR(9)," ")
  8311.  
  8312. * Reduce multiple spaces to a single space
  8313. DO WHILE AT('  ',m.s1) > 0
  8314.    m.s1 = STRTRAN(m.s1,'  ',' ')
  8315. ENDDO
  8316.  
  8317. ret_str = ""
  8318. DO CASE
  8319. CASE m.w_num > 1
  8320.    DO CASE
  8321.    CASE AT(" ",m.s1,m.w_num-1) = 0   && No word w_num.  Past end of string.
  8322.       m.ret_str = ""
  8323.    CASE AT(" ",m.s1,m.w_num) = 0     && Word w_num is last word in string.
  8324.       m.ret_str = SUBSTR(m.s1,AT(" ",m.s1,m.w_num-1)+1,255)
  8325.    OTHERWISE                         && Word w_num is in the middle.
  8326.       m.strt_pos = AT(" ",m.s1,m.w_num-1)
  8327.       m.ret_str  = SUBSTR(m.s1,strt_pos,AT(" ",m.s1,m.w_num)+1 - strt_pos)
  8328.    ENDCASE
  8329. CASE m.w_num = 1
  8330.    IF AT(" ",m.s1) > 0               && Get first word.
  8331.       m.ret_str = SUBSTR(m.s1,1,AT(" ",m.s1)-1)
  8332.    ELSE                              && There is only one word.  Get it.
  8333.       m.ret_str = m.s1
  8334.    ENDIF
  8335. ENDCASE
  8336. RETURN ALLTRIM(m.ret_str)
  8337.  
  8338.  
  8339. * GETCNAME - Generates a name for a clause.  Will take name from a
  8340. *              generator directive stored in a snippet if present,
  8341. *              or generates a generic name otherwise.  The name is
  8342. *              designated by a #NAME name directive
  8343. *
  8344. *!*****************************************************************************
  8345. *!
  8346. *!       Function: GETCNAME
  8347. *!
  8348. *!      Called by: SETCLAUSEFLAGS     (procedure in GENSCRN.PRG)
  8349. *!               : ORCLAUSEFLAGS      (procedure in GENSCRN.PRG)
  8350. *!               : ANYVALID           (procedure in GENSCRN.PRG)
  8351. *!               : ANYWHEN            (procedure in GENSCRN.PRG)
  8352. *!               : ANYMESSAGE         (procedure in GENSCRN.PRG)
  8353. *!               : ANYERROR           (procedure in GENSCRN.PRG)
  8354. *!
  8355. *!*****************************************************************************
  8356. FUNCTION getcname
  8357. PARAMETERS m.snippet
  8358. PRIVATE dirname
  8359. IF ATC("#NAME",m.snippet) > 0
  8360.    m.dirname = MLINE(m.snippet, ATCLINE('#NAME',m.snippet))
  8361.    m.dirname = UPPER(ALLTRIM(SUBSTR(m.dirname,AT(' ',m.dirname)+1)))
  8362.    IF !EMPTY(m.dirname)
  8363.       RETURN m.dirname
  8364.    ENDIF
  8365. ENDIF
  8366. RETURN LOWER(SYS(2015))
  8367.  
  8368. *
  8369. * NOTEAREA - Note that we are using this area so that we can clean up at exit
  8370. *
  8371. *!*****************************************************************************
  8372. *!
  8373. *!      Procedure: NOTEAREA
  8374. *!
  8375. *!      Called by: OPENPROJDBF()      (function  in GENSCRN.PRG)
  8376. *!               : PREPSCREENS()      (function  in GENSCRN.PRG)
  8377. *!
  8378. *!*****************************************************************************
  8379. PROCEDURE notearea
  8380. g_areas[m.g_areacount] = SELECT()
  8381. m.g_areacount = m.g_areacount + 1
  8382. RETURN
  8383.  
  8384. *
  8385. * CLEARAREAS - Clear the ones we opened.
  8386. *
  8387. *!*****************************************************************************
  8388. *!
  8389. *!      Procedure: CLEARAREAS
  8390. *!
  8391. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  8392. *!
  8393. *!*****************************************************************************
  8394. PROCEDURE clearareas
  8395. FOR i = 1 TO m.g_areacount
  8396.    SELECT g_areas[m.i]
  8397.    USE
  8398. ENDFOR
  8399. RETURN
  8400.  
  8401. *
  8402. * INITTICK, TICK, and TOCK - Profiling functions
  8403. *
  8404. *!*****************************************************************************
  8405. *!
  8406. *!      Procedure: INITTICK
  8407. *!
  8408. *!      Called by: GENSCRN.PRG
  8409. *!
  8410. *!*****************************************************************************
  8411. PROCEDURE inittick
  8412. IF TYPE("ticktock") = "U"
  8413.    PUBLIC ticktock[10]
  8414. ENDIF
  8415. ticktock = 0
  8416.  
  8417. *!*****************************************************************************
  8418. *!
  8419. *!       Function: TICK
  8420. *!
  8421. *!      Called by: GENSCRN.PRG
  8422. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8423. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8424. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  8425. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  8426. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8427. *!
  8428. *!*****************************************************************************
  8429. FUNCTION tick
  8430. PARAMETER m.bucket
  8431. ticktock[bucket] = ticktock[bucket] - SECONDS()
  8432.  
  8433. *!*****************************************************************************
  8434. *!
  8435. *!       Function: TOCK
  8436. *!
  8437. *!      Called by: CLEANUP            (procedure in GENSCRN.PRG)
  8438. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8439. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8440. *!               : FINDSECTION()      (function  in GENSCRN.PRG)
  8441. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  8442. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8443. *!
  8444. *!*****************************************************************************
  8445. FUNCTION tock
  8446. PARAMETER m.bucket
  8447. ticktock[bucket] = ticktock[bucket] + SECONDS()
  8448.  
  8449. *
  8450. * Display a status message on the status bar at the bottom of the screen
  8451. *
  8452. *!*****************************************************************************
  8453. *!
  8454. *!      Procedure: PUTMSG
  8455. *!
  8456. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8457. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8458. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8459. *!               : EXTRACTPROCS       (procedure in GENSCRN.PRG)
  8460. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8461. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8462. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8463. *!
  8464. *!*****************************************************************************
  8465. PROCEDURE putmsg
  8466. PARAMETER m.msg
  8467. IF m.g_graphic
  8468.    SET MESSAGE TO msg
  8469. ENDIF
  8470.  
  8471. *
  8472. * VERSIONCAP - Return platform name suitable for display
  8473. *
  8474. *!*****************************************************************************
  8475. *!
  8476. *!       Function: VERSIONCAP
  8477. *!
  8478. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8479. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8480. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  8481. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8482. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8483. *!               : COMMENTBLOCK       (procedure in GENSCRN.PRG)
  8484. *!
  8485. *!*****************************************************************************
  8486. FUNCTION versioncap
  8487. PARAMETER m.strg
  8488. DO CASE
  8489. CASE strg = "DOS"
  8490.    RETURN "MS-DOS"
  8491. CASE strg = "WINDOWS"
  8492.    RETURN "Windows"
  8493. CASE strg = "MAC"
  8494.    RETURN "Macintosh"
  8495. CASE strg = "UNIX"
  8496.    RETURN "UNIX"
  8497. OTHERWISE
  8498.    RETURN strg
  8499. ENDCASE
  8500.  
  8501. *
  8502. * MULTIPLAT - Returns TRUE if we are generating for multiple platforms
  8503. *
  8504. *!*****************************************************************************
  8505. *!
  8506. *!       Function: MULTIPLAT
  8507. *!
  8508. *!      Called by: DISPATCHBUILD      (procedure in GENSCRN.PRG)
  8509. *!               : GENCLEANUP         (procedure in GENSCRN.PRG)
  8510. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8511. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8512. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8513. *!
  8514. *!*****************************************************************************
  8515. FUNCTION multiplat
  8516. RETURN IIF(m.g_allplatforms AND m.g_numplatforms > 1, .T. , .F.)
  8517.  
  8518. *
  8519. * SEEKHEADER - Find the header for this screen/platform
  8520. *
  8521. *!*****************************************************************************
  8522. *!
  8523. *!      Procedure: SEEKHEADER
  8524. *!
  8525. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  8526. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8527. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8528. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8529. *!               : GENRELATIONS       (procedure in GENSCRN.PRG)
  8530. *!               : BUILDFMT           (procedure in GENSCRN.PRG)
  8531. *!               : GENGIVENREAD       (procedure in GENSCRN.PRG)
  8532. *!
  8533. *!*****************************************************************************
  8534. PROCEDURE seekheader
  8535. PARAMETER m.i
  8536. IF g_screens[m.i,6]
  8537.    GO TOP
  8538. ELSE
  8539.    LOCATE FOR platform = g_screens[m.i,7] AND objtype = c_otscreen
  8540. ENDIF
  8541.  
  8542. *
  8543. * GETPLATNAME - Return the platform for a screen
  8544. *
  8545.  
  8546. *!*****************************************************************************
  8547. *!
  8548. *!       Function: GETPLATNAME
  8549. *!
  8550. *!      Called by: GENCLEANUP         (procedure in GENSCRN.PRG)
  8551. *!               : GENPROCEDURES      (procedure in GENSCRN.PRG)
  8552. *!               : GENSECT1           (procedure in GENSCRN.PRG)
  8553. *!               : GENSECT2           (procedure in GENSCRN.PRG)
  8554. *!               : GENVALIDBODY       (procedure in GENSCRN.PRG)
  8555. *!               : GENWHENBODY        (procedure in GENSCRN.PRG)
  8556. *!               : ACTICLAUSE         (procedure in GENSCRN.PRG)
  8557. *!               : DEATCLAUSE         (procedure in GENSCRN.PRG)
  8558. *!               : SHOWCLAUSE         (procedure in GENSCRN.PRG)
  8559. *!
  8560. *!*****************************************************************************
  8561. FUNCTION getplatname
  8562. PARAMETER m.plnum
  8563. IF g_screens[m.plnum,6]
  8564.    RETURN "DOS"
  8565. ELSE
  8566.    RETURN platform
  8567. ENDIF
  8568.  
  8569.  
  8570. *!*****************************************************************************
  8571. *!
  8572. *!      Procedure: INSERTFILE
  8573. *!
  8574. *!      Called by: GENINSERTCODE      (procedure in GENSCRN.PRG)
  8575. *!
  8576. *!          Calls: WRITECODE          (procedure in GENSCRN.PRG)
  8577. *!
  8578. *!*****************************************************************************
  8579. PROCEDURE insertfile
  8580. PARAMETER m.incfn, m.scrnno, m.insetup, m.platname
  8581. PRIVATE m.oldals, m.insdbfname, m.oldmline, m.fptname
  8582.  
  8583. * Search for the file in the current directory, along the FoxPro path, and along
  8584. * the DOS path.
  8585. IF !FILE(m.incfn)
  8586.    DO CASE
  8587.    CASE FILE(FULLPATH(m.incfn))
  8588.       m.incfn = FULLPATH(m.incfn)
  8589.    CASE FILE(FULLPATH(m.incfn,1))
  8590.       m.incfn = FULLPATH(m.incfn,1)
  8591.    ENDCASE
  8592. ENDIF
  8593.  
  8594. IF FILE((m.incfn))
  8595.    m.oldals = ALIAS()
  8596.    m.insdbfname = SYS(3)+".DBF"
  8597.    m.oldmline = _MLINE
  8598.  
  8599.    * The following lines create a temporary file with a single memo field
  8600.    * and appends the inserted file into the memo field. Effectively creating
  8601.    * a code snippet. This allows the standard procedure for generating code
  8602.    * snippets to be call to process the inserted file. This in turn allows
  8603.    * the include file to contain generator directives.
  8604.    CREATE TABLE (m.insdbfname) (inscode m)
  8605.    APPEND BLANK
  8606.    APPEND MEMO inscode FROM (m.incfn)
  8607.  
  8608.    \** Start of inserted file <<m.incfn>> <<REPLICATE(m.g_horiz,32)+"start">>
  8609.  
  8610.    * Make a recursive call to the standard snippet generation procedure
  8611.    DO writecode WITH inscode, m.platname, 1, 0, m.scrnno, m.insetup
  8612.  
  8613.    \** End of inserted file <<m.incfn>> <<REPLICATE(m.g_horiz,36)+"end">>
  8614.    \
  8615.  
  8616.    USE
  8617.    DELETE FILE (m.insdbfname)
  8618.    m.fptname = forceext(m.insdbfname,"FPT")
  8619.    IF FILE(m.fptname)
  8620.       DELETE FILE (m.fptname)
  8621.    ENDIF
  8622.  
  8623.    SELECT (m.oldals)
  8624.    _MLINE=oldmline
  8625. ELSE
  8626.    \*
  8627.    \* Inserted file <<m.incfn>> not found!
  8628.    \*
  8629. ENDIF
  8630. RETURN
  8631.  
  8632. *!*****************************************************************************
  8633. *!
  8634. *!      Function: VERSNUM
  8635. *!
  8636. *!*****************************************************************************
  8637. FUNCTION versnum
  8638. * Return string corresponding to FoxPro version number
  8639. RETURN wordnum(vers(),2)
  8640.  
  8641. *: EOF: GENSCRN.PRG
  8642.